-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsearch.xml
More file actions
202 lines (202 loc) · 51.7 KB
/
search.xml
File metadata and controls
202 lines (202 loc) · 51.7 KB
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><![CDATA[docker-compose 启动 mysql 报错]]></title>
<url>%2F2019%2F04%2F29%2Fdocker-compose-up-mysql%2F</url>
<content type="text"><![CDATA[docker-compose 启动 mysql 报错 (Error starting userland proxy: Bind for 0.0.0.0:3306 failed: port is already) ,这个是因为mac 本地的mysql已经启动了,并且占用了3306端口,这个时候需要进行如下操作: 方案1: 直接启动一个新的端口,但是使用时会出现错误,不能彻底解决。方案2: 找到mac 的设置页面 然后找到mysql: 进入mysql 中stop mysql server: 然后docker-compose up 重新启动 即可。]]></content>
<categories>
<category>docker</category>
</categories>
<tags>
<tag>docker</tag>
</tags>
</entry>
<entry>
<title><![CDATA[音频格式转化 m4a 转 wav]]></title>
<url>%2F2019%2F04%2F28%2Fm4a-wav%2F</url>
<content type="text"><![CDATA[还是因为音频合成的原因,合成的音频是m4a 格式,上传到七牛后,形成的链接,浏览器可以播放。但是手机不行,m4a 是偏视频格式,用原有的avplayer 方法不能播放,所以需要进行转化后上传播放。 代码如下:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116-(void)convetM4aToWav:(NSURL *)originalUrldestUrl:(NSString *)destUrlStrcompleted:(void (^)(NSError *error)) completed {NSLog(@"\n\n\nM4A-WAV\n\n\n");if ([[NSFileManager defaultManager] fileExistsAtPath:destUrlStr]) {[[NSFileManager defaultManager] removeItemAtPath:destUrlStr error:nil];}NSURL *destUrl = [NSURL fileURLWithPath:destUrlStr];AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:originalUrl options:nil];//读取原始文件信息NSError *error = nil;AVAssetReader *assetReader = [AVAssetReader assetReaderWithAsset:songAsset error:&error];if (error) {NSLog (@"error: %@", error);completed(error);return;}AVAssetReaderOutput *assetReaderOutput = [AVAssetReaderAudioMixOutputassetReaderAudioMixOutputWithAudioTracks:songAsset.tracksaudioSettings: nil];if (![assetReader canAddOutput:assetReaderOutput]) {NSLog (@"can't add reader output... die!");completed(error);return;}[assetReader addOutput:assetReaderOutput];AVAssetWriter *assetWriter = [AVAssetWriter assetWriterWithURL:destUrlfileType:AVFileTypeCoreAudioFormaterror:&error];if (error) {NSLog (@"error: %@", error);completed(error);return;}AudioChannelLayout channelLayout;memset(&channelLayout, 0, sizeof(AudioChannelLayout));channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,[NSNumber numberWithFloat:8000], AVSampleRateKey,[NSNumber numberWithInt:2], AVNumberOfChannelsKey,[NSNumber numberWithInt:16], AVLinearPCMBitDepthKey,[NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,[NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,[NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey,nil];AVAssetWriterInput *assetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudiooutputSettings:outputSettings];if ([assetWriter canAddInput:assetWriterInput]) {[assetWriter addInput:assetWriterInput];} else {NSLog (@"can't add asset writer input... die!");completed(error);return;}assetWriterInput.expectsMediaDataInRealTime = NO;[assetWriter startWriting];[assetReader startReading];AVAssetTrack *soundTrack = [songAsset.tracks objectAtIndex:0];CMTime startTime = CMTimeMake (0, soundTrack.naturalTimeScale);[assetWriter startSessionAtSourceTime:startTime];__block UInt64 convertedByteCount = 0;dispatch_queue_t mediaInputQueue = dispatch_queue_create("mediaInputQueue", NULL);[assetWriterInput requestMediaDataWhenReadyOnQueue:mediaInputQueueusingBlock: ^{while (assetWriterInput.readyForMoreMediaData) {CMSampleBufferRef nextBuffer = [assetReaderOutput copyNextSampleBuffer];if (nextBuffer) {// append buffer[assetWriterInput appendSampleBuffer: nextBuffer];// NSLog (@"appended a buffer (%zu bytes)",// CMSampleBufferGetTotalSampleSize (nextBuffer));convertedByteCount += CMSampleBufferGetTotalSampleSize (nextBuffer);} else {[assetWriterInput markAsFinished];[assetWriter finishWritingWithCompletionHandler:^{}];[assetReader cancelReading];NSDictionary *outputFileAttributes = [[NSFileManager defaultManager]attributesOfItemAtPath:[destUrl path]error:nil];NSLog (@"FlyElephant %lld",[outputFileAttributes fileSize]);break;}}NSLog(@"转换结束");// 删除临时temprecordAudio.m4a文件NSError *removeError = nil;if ([[NSFileManager defaultManager] fileExistsAtPath:[originalUrl path]]) {BOOL success = [[NSFileManager defaultManager] removeItemAtPath:[originalUrl path] error:&removeError];if (!success) {NSLog(@"删除临时temprecordAudio.m4a文件失败:%@",removeError);completed(removeError);}else{NSLog(@"删除临时temprecordAudio.m4a文件:%@成功",originalUrl);completed(removeError);}}else {NSLog(@"文件不存在");}}];} 文档目录相关代码如下:12345678910111213141516171819202122232425- (NSString *)documentPath{NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;return documentPath;}- (NSString *)audioCacheFolder{NSString *audioFolder = [[self documentPath] stringByAppendingPathComponent:AUDIOCACHE];if (![FILEMANAGER fileExistsAtPath:audioFolder]) {NSError *error = nil;[FILEMANAGER createDirectoryAtPath:audioFolder withIntermediateDirectories:YES attributes:nil error:&error];if (error) {NSLog(@"音频文件夹创建失败----%@", error);}}return audioFolder;}//用url作为文件名- (NSString *)audioFilePath:(NSString *)audioURL{NSString *fileName = [audioURL stringByReplacingOccurrencesOfString:@"/" withString:@"-"];return [[self audioCacheFolder] stringByAppendingPathComponent:fileName];}]]></content>
<categories>
<category>IOS</category>
</categories>
<tags>
<tag>音视频</tag>
</tags>
</entry>
<entry>
<title><![CDATA[通过lame 进行音频格式转化]]></title>
<url>%2F2019%2F04%2F08%2Flame%E8%BD%AC%E5%8C%96%2F</url>
<content type="text"><![CDATA[背景 因为上一篇音频合成中遇到了一个问题,合成工具不支持wav音频格式转化,而且录音所得的wav格式 是无损的格式,标准的wav采样率为44100Hz,也是CD标准格式;mp3属于有损压缩文件,不过体积小,便于保存。lame 下载下来不能直接用 依赖的东西 :lame库下载地址lame 静态库打包工具地址 操作步骤: 把下载的lame和build-lame.sh放在一个文件夹下 注意 # build-lame.sh 中 #directories SOURCE=”lame”这里lame是来源文件名 在创建的目录下执行 bulid 脚本 1sudo ./build-lame.sh 下面 fat-lame 中就是我们想要的东西,将.a 文件和.h文件放入项目即可 wav 转map3 相关代码 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374#define AUDIOCACHE @"音频存放目录"文件管理#define FILEMANAGER [NSFileManager defaultManager]- (NSString *)documentPath{NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;return documentPath;}- (NSString *)audioCacheFolder{NSString *audioFolder = [[self documentPath] stringByAppendingPathComponent:AUDIOCACHE];if (![FILEMANAGER fileExistsAtPath:audioFolder]) {NSError *error = nil;[FILEMANAGER createDirectoryAtPath:audioFolder withIntermediateDirectories:YES attributes:nil error:&error];if (error) {NSLog(@"音频文件夹创建失败----%@", error);}}return audioFolder;}//用url作为文件名- (NSString *)audioFilePath:(NSString *)audioURL{NSString *fileName = [audioURL stringByReplacingOccurrencesOfString:@"/" withString:@"-"];return [[self audioCacheFolder] stringByAppendingPathComponent:fileName];}//转化方法- (NSString *)audioPCMtoMP3:(NSString *)wavPath {NSString *cafFilePath = wavPath;NSString *mp3FilePath = [self audioFilePath];if([FILEMANAGER removeItemAtPath:mp3FilePath error:nil]){ NSLog(@"删除原MP3文件");}@try{int read, write;FILE *pcm = fopen([cafFilePath cStringUsingEncoding:1], "rb");//source 被转换的音频文件位置fseek(pcm, 4*1024, SEEK_CUR);//skip file headerFILE *mp3 = fopen([mp3FilePath cStringUsingEncoding:1], "wb");//output 输出生成的Mp3文件位置const int PCM_SIZE = 8192;const int MP3_SIZE = 8192;short int pcm_buffer[PCM_SIZE*2];unsigned char mp3_buffer[MP3_SIZE];lame_t lame = lame_init();// lame_set_in_samplerate(lame, 22050.0);lame_set_in_samplerate(lame, 4000.0);lame_set_VBR(lame, vbr_default); lame_init_params(lame);do {read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);if (read == 0) write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);else write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);fwrite(mp3_buffer, write, 1, mp3);}while (read != 0);lame_close(lame);fclose(mp3);fclose(pcm);} @catch (NSException *exception) {NSLog(@"%@",[exception description]);return @"";} @finally {return mp3FilePath;}} refer : https://www.jianshu.com/p/864a9fbaa79e]]></content>
<categories>
<category>IOS</category>
</categories>
<tags>
<tag>音视频</tag>
</tags>
</entry>
<entry>
<title><![CDATA[使用gitlab+fastlane进行自动化构建]]></title>
<url>%2F2019%2F03%2F29%2Fmy-hello-world%2F</url>
<content type="text"><![CDATA[持续集成优点:1、缩减开发周期,快速迭代版本 2、提供分发效率,测试人员以及相关人员无需等待开发人员打包 3、减少重复操作,高效打包,减轻开发人员工作量。 4 . 将代码推送到新的分支,CI 服务器就会为您运行测试。 如果 job 都是绿色 的,你的代码是 OK 的。 5 . 如果给定分支中的所有测试都是绿色的,则可以让 CI 服务器自动将代码部署到生产环境中。 这就是所谓的连续部署(Continuous Deployment) 。 6 . 减少 code review 时间 搭建方法运行环境要求 gitlab gitlabrunner fastlane 钉钉机器人 搭建步骤1. 安装 gitlab runner Install GitLab Runner on macOS(我的是 mac 环境所以选择的 Install GitLab Runner on macOS)*1.Download the binary for your system 1sudo curl --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64 2.Give it permissions to execute: 1sudo chmod +x /usr/local/bin/gitlab-runner 2. 注册 gitlab runner To register a Runner under macOS:*1. Run the following command: 1gitlab-runner register 2Enter your GitLab instance URL: (你 gitlab 的地址) 12Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )https://gitlab.com Enter the token you obtained to register the Runner:(CI/CD 中项目的 token) 12Please enter the gitlab-ci token for this runnerxxx Enter a description for the Runner, you can change this later in GitLab’s UI: 12Please enter the gitlab-ci description for this runner[hostame] my-runner Enter the tags associated with the Runner, you can change this later in GitLab’s UI: 12Please enter the gitlab-ci tags for this runner (comma separated):my-tag,another-tag 6 Enter the Runner executor: 12Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell:shel 3. 编写 yml 文件配置项目的 yml 文件进行相应的 job 操作校验 yml 文件是否正确本地调试 yml 文件安装 jq 这个输出报告的时候用 1brew install jq 下面是我的 yml 文件仅供参考 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172//构建阶段stages:- build- buildAndUpload- failure//构建前配置before_script:- export LANG=en_US.UTF-8- export FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT=120# build for branch test build and upload to pgyer.job1://注册 runner tag名 可以多个tags:- wangweitagsstage: buildAndUploadscript:# - sh ./Shell/dingtalk.sh "新版本" "# 构建新版本(justademo)"- echo $(pwd)- echo "build job1"- pod install- git reset --hard// fastlane 自动化构建- fastlane dev// 输出相关的git commit等相关信息- export pgyerDes=`git log -10 --oneline | cut -d " " -f2- | grep -E '^\[.*|.*finish$'`- echo ${pgyerDes}- echo $(pwd)- echo $(ls)- export result=$(curl -# -F "file=@../product/LZMDYW.ipa" -F "_api_key=2c34b4faa9e0559667c828f415f7ebee" -F "userKey=1ce44e894fbe779bbf23e75d12c482d8" -F "buildUpdateDescription=${pgyerDes}" https://www.pgyer.com/apiv2/app/upload)- echo ${result} | jq- export buildKey=`echo ${result} | jq '. | .data.buildKey' | awk -F '"' '{print $2}'`buildQRCodeURL=`echo ${result} | jq '. | .data.buildQRCodeURL' | awk -F '"' '{print $2}'`buildVersion=`echo ${result} | jq '. | .data.buildVersion+"("+.data.buildBuildVersion+")"' | awk -F '"' '{print $2}'`buildUpdated=`echo ${result} | jq '. | .data.buildUpdated' | awk -F '"' '{print $2}'`change_log=`git log -20 --oneline | cut -d " " -f2- | grep -E '^\[.*|.*finish$' | awk '{{printf"##### %s; \n",$0}}'`- export text="### 版本"${buildVersion}" \n > 更新记录 \n\n > "${change_log}" \n\n > \n##### [下载链接](https://www.pgyer.com/"${buildKey}")\n\n###### 上传日期:"${buildUpdated}""//钉钉脚本- sh ./Shell/dingtalk.sh "新版本" "$text"only:- /^test.*$/# build for branch only build.job2:tags:- wangweitagsstage: buildscript:# - sh ./Shell/dingtalk.sh "新版本" "# 构建新版本(justademo)"- echo $(pwd)- echo "build job2"- pod install- git reset --hard//fastlen 构建- fastlane CI_devonly:- dev- master# notify when a build has erroredbuild_failure_job:tags:- wangweitagsstage: failurescript:// 丁丁脚本- sh ../Shell/dingtalk.sh "新版本" "# 构建失败(LZMDYW)"when: on_failure 4. fastlane 构建https://docs.fastlane.tools/getting-started/ios/setup/ (1)安装 xcode 命令行工具 xcode-select –install,如果没有安装,会弹出对话框,点击安装。如果提示 xcode-select: error: command line tools are already installed, use “Software Update” to install updates 表示已经安装 #####(2) 安装 Fastlanesudo gem install fastlane -NV 或是 brew cask install fastlane 我这里使用 gem 安装的安装完了执行 fastlane –version,确认下是否安装完成和当前使用的版本号。 (3)初始化 Fastlanecd 到你的项目目录执行fastlane init (4)打包到蒲公英1fastlane add_plugin pgyer 自己的 fastlane 脚本 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051default_platform(:ios)platform :ios dodesc "Description of what the lane does"lane :dev dosigh(force: true,username: "开发者账号",app_identifier: "bundleid",output_path: '.ipa包输出路径',adhoc: true (是否adhoc))build_app(workspace: "XXXX.xcworkspace",configuration: "Debug", (scheme配置)scheme: "XXXX",export_method: "ad-hoc",output_directory:".ipa包输出路径",include_bitcode:true,)// 打包到蒲公英pgyer(api_key: "",user_key: "",update_description: "scheme is dev, update by fastlane")endlane :CI_dev dosigh(force: true,username: "开发者账号",app_identifier: "bundleid",output_path: '.ipa包输出路径',adhoc: true (是否adhoc))build_app(workspace: "XXXX.xcworkspace",configuration: "Debug", (scheme配置)scheme: "XXXX",export_method: "ad-hoc",output_directory:".ipa包输出路径",include_bitcode:true,)endend 5.钉钉通知12345678910111213#! bin/bashecho $2curl ' 放自己注册的钉钉机器人的token' \-H "Content-Type:application/json" \-d "{ \markdown:{ \title:'$1', \text:'$2' \}, \msgtype:'markdown' \}" 6 fastlane 构建注意事项(三天两头的加测试机,手动更新配置文件更新实在是太麻烦了,要不老是提示双重认证)refer:https://blog.csdn.net/weixin_34293911/article/details/87011860 fastlane iOS 双重认证 更新配置文件这个时候就用到这个,他可以自动管理配置开发者等信息https://github.com/fastlane/fastlane/tree/master/spaceship 访问 AppleId 管理站 找到 安全 - App 专用密码,生成一个专用密码 配置环境变量 vim ~/.bash_profile export 1FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD=YOUR_PSD 执行 fastlane spaceauth -u abcd@qq.com 按提示获取 session 信息。 复制 session 信息(很长一大段) 配置环境变量 vim ~/.bash_profile 1export FASTLANE_SESSION='YOUR SESSION']]></content>
<categories>
<category>IOS</category>
</categories>
<tags>
<tag>自动化构建</tag>
</tags>
</entry>
<entry>
<title><![CDATA[iOS音频合并的多种方式]]></title>
<url>%2F2019%2F03%2F28%2Faduiomix%2F</url>
<content type="text"><![CDATA[最近在做音频合并这块需求,然后遇见了几种形式,这里做一个总结。 第一种 可网络可本地 ,可调整音量,范围等 定制化还比较高 1.基本类介绍refer:https://docs.microsoft.com/en-us/dotnet/api/avfoundation.avcomposition?view=xamarin-ios-sdk-12 AVAsset 媒体信息 AVURLAsset 根据URL路径创建的媒体信息 AVAssetTrack 资源轨道,包括音频轨道和视频轨道 AVMutableAudioMixInputParameters音频操作参数 AVMutableComposition 继承自AVComposition,用于从现有Asset创建新合成的可变对象。包含多个轨道的媒体信息,可以添加、删除轨道 AVAssetExportSession 导出 具体实现如下:1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798#pragma mark - 音频与音频的合并+ (void)mixOriginalAudio:(NSURL *)originalAudioPathoriginalAudioVolume:(float)originalAudioVolumebgAudioPath:(NSURL *)bgAudioPathbgAudioVolume:(float)bgAudioVolumeoutPutFileName:(NSString *)fileNamecompletionBlock:(CompletionBlock)completionBlock{if (originalAudioPath == nil) {return;}if (bgAudioPath == nil) {return;}if (originalAudioVolume > 1.0) {originalAudioVolume = 1.0f;}if (originalAudioVolume < 0) {originalAudioVolume = 0.0f;}if (bgAudioVolume > 1.0) {bgAudioVolume = 1.0f;}if (bgAudioVolume < 0) {bgAudioVolume = 0.0f;}dispatch_async(dispatch_get_global_queue(0, 0), ^{AVURLAsset *originalAudioAsset = [AVURLAsset assetWithURL:originalAudioPath];AVURLAsset *bgAudioAsset = [AVURLAsset assetWithURL:bgAudioPath];AVMutableComposition *compostion = [AVMutableComposition composition];AVMutableCompositionTrack *originalAudio = [compostion addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:0];[originalAudio insertTimeRange:CMTimeRangeMake(kCMTimeZero, originalAudioAsset.duration) ofTrack:[originalAudioAsset tracksWithMediaType:AVMediaTypeAudio].firstObject atTime:kCMTimeZero error:nil];AVMutableCompositionTrack *bgAudio = [compostion addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:0];[bgAudio insertTimeRange:CMTimeRangeMake(kCMTimeZero, originalAudioAsset.duration) ofTrack:[bgAudioAsset tracksWithMediaType:AVMediaTypeAudio].firstObject atTime:kCMTimeZero error:nil];//播放速率会受影响NSUInteger originalAudioAssetTotalSeconds = CMTimeGetSeconds(originalAudioAsset.duration);NSUInteger bgAudioAssetTotalSeconds = CMTimeGetSeconds(bgAudioAsset.duration);if (originalAudioAssetTotalSeconds>bgAudioAssetTotalSeconds) {[bgAudio scaleTimeRange:CMTimeRangeMake(kCMTimeZero, bgAudioAsset.duration) toDuration:originalAudioAsset.duration];}/** 得到对应轨道中的音频声音信息,并更改 */AVMutableAudioMixInputParameters *originalAudioParameters = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:originalAudio];[originalAudioParameters setVolume:originalAudioVolume atTime:kCMTimeZero];AVMutableAudioMixInputParameters *bgAudioParameters = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:bgAudio];[bgAudioParameters setVolume:bgAudioVolume atTime:kCMTimeZero];/** 赋给对应的类 */AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];audioMix.inputParameters = @[ originalAudioParameters, bgAudioParameters ];AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:compostion presetName:AVAssetExportPresetAppleM4A];/** 设置输出路径 */NSURL *outputPath = [self exporterAudioPathWithFileName:fileName];session.audioMix = audioMix;session.outputURL = outputPath;session.outputFileType = AVFileTypeAppleM4A;session.shouldOptimizeForNetworkUse = YES;[session exportAsynchronouslyWithCompletionHandler:^{dispatch_async(dispatch_get_main_queue(), ^{switch ([session status]) {case AVAssetExportSessionStatusFailed: {NSLog(@"合成失败:%@", [[session error] description]);completionBlock(NO, outputPath);} break;case AVAssetExportSessionStatusCancelled: {completionBlock(NO, outputPath);} break;case AVAssetExportSessionStatusCompleted: {completionBlock(YES, outputPath);} break;default: {completionBlock(NO, outputPath);} break;}});}];});} ⚠️压缩时长 更改给定时间范围内所有轨道的时长。123456- (void)scaleTimeRange:(CMTimeRange)timeRangetoDuration:(CMTime)duration;参数timeRange:要缩放的合成轨道的时间范围。参数duration:新的时长。受缩放操作影响的每个轨道段将以等于其结果时间映射的source.duration/target.duration的速率呈现。 ⚠️设置背景音乐时长和插入时间12[bgAudio insertTimeRange:CMTimeRangeMake(kCMTimeZero, originalAudioAsset.duration) ofTrack:[bgAudioAsset tracksWithMediaType:AVMediaTypeAudio].firstObject atTime:kCMTimeZero error:nil];因为我的需求是加入背景音乐给录音,所以将背景音乐从头插入kCMTimeZero 插入时长为录音的时长 originalAudioAsset.duration ⚠️注意导出格式首先是输出路径,切记切记这里的后缀一定要和上面选择的呼应,比如我写的格式为AVAssetExportPresetAppleM4A那么我的文件后缀就需要为.m4a,如果用.MP3这种的话是无法正确生成出文件的,有可能会出现空文件的存在.一定要注意!!! ⚠️传入网络链接的时候 需要将网络链接下载下来转成本地路径进行传入。refer: https://github.com/Anny-github/AudioPlayerManager 第二种 本地音频合并,可以调整音量https://github.com/daybreak1024/ZLMMixAudio 第三种 可以网络或者本地合并,但是无法定制化,因为用的别人的静态库😢https://github.com/QuintGao/GKDubbingDemo]]></content>
<categories>
<category>IOS</category>
</categories>
<tags>
<tag>mix</tag>
</tags>
</entry>
<entry>
<title><![CDATA[UItouch事件被tableview拦截]]></title>
<url>%2F2019%2F02%2F20%2Fuitouch%2F</url>
<content type="text"><![CDATA[最近做项目用到了手写签名的功能,手写签名的view是通过UItouch相关方法画线实现的,因为页面UI是列表形式,手写签名view 需要添加到tableview的footview上,这个时候就出现了问题,手写签名view的touch被tableview拦截了,这个时候再去操作view 签名的时候 是不能成功呢,而且页面会滚动。 下面我记录一下我的处理方式1.一开始我以为像网上的方式,给tableview创建一个子类然后引入touch 方法:refer https://blog.csdn.net/qq_42839789/article/details/81501832但是view的touch 会覆盖tableviewtouch 并不能解决问题。2.这个时候我想到hittest 方法通过事件响应机制,判断触摸的view是不是签名view 如果是让tableview暂时停止滚动,如果不是正常滚动。具体实现如下:123456789101112131415161718192021222324#import <UIKit/UIKit.h>@interface WYTouchTableView : UITableView@end#import "WYTouchTableView.h"#import "HJSignatureView.h"@implementation WYTouchTableView- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{UIView *viewReturn =[super hitTest:point withEvent:event];//在touchView区域if ([viewReturn isKindOfClass:[HJSignatureView class]]) {self.scrollEnabled = NO;return viewReturn;}else{self.scrollEnabled = YES;}//不在touchView区域,正常操作return viewReturn;}@end]]></content>
<categories>
<category>IOS</category>
</categories>
<tags>
<tag>someBug</tag>
</tags>
</entry>
<entry>
<title><![CDATA[创建静态私有库]]></title>
<url>%2F2019%2F01%2F28%2F%E9%9D%99%E6%80%81%E5%BA%93%2F</url>
<content type="text"><![CDATA[在上篇文章中介绍了Cocoapods私有库的创建有些时候我们并不希望别人引用咱们的库的时候看见我们的相关实现代码,这个时候就需要将相关代码,打成静态库。第一 .a和.framwork的区别:iOS静态库形式和动态库形式:静态库:.a和.framework动态库:.dylib和.framework.a是一个纯二进制文件,.framework中除了有二进制文件外还有资源文件。.a文件不能直接使用,至少要有.h文件配合,.framework文件可以直接使用。.a + .h + sourceFile = .framework第二 我们可以通过两种方式进行静态库的打包,1是手动打包比较麻烦,网上有好多相关教程,这里就不一一介绍了2命令行打包,这个比较简单,一条命令即可1)安装打包插件终端执行以下命令sudo gem install cocoapods-packager2)进入私有库目录 然后将源码导入classes 目录下 然后执行下面的命令pod package demo.podspec –library –force其中–library指定打包成.a文件,如果不带上将会打包成.framework文件。–force是指强制覆盖。这个时候目录下会多出一个文件夹然后将framework文件复制到aesEncrypts/Framework/下面第三 配置相关私有库信息1)将相关framework导入私有库目录下2)配置spec文件 管理.framework跟管理.a类似,同样是生成通用framework。只不过podspec有点不同。.a是s.vendored_libraries,.framework是s.vendored_frameworks。3).tag标记,并且上传123/// 第一次需要在前面加一个vgit tag "v1.0.0"git push --tags 6.验证.podspec 方式一// 加上–verbose验证失败会显示详细的报错信息pod spec lint aesEncrypts.podspec –verbose方式二pod spec lint7.发布自己的.podspec到cocoapodspod trunk push aesEncrypts.podspec如果有警告用:pod trunk push aesEncrypts.podspec –allow-warnings 注意:注意cocopods 版本 不要用beta 版本进行创建,要不lib 验证可以通过,但是spec 方式验证会出错。pod spec相对于pod lib 会更为精确,pod lib相当于只验证一个本地仓库,pod spec会同时验证本地仓库和远程仓库。 如果spec文件不通过,spec 文件是不能上传到远程仓库]]></content>
<categories>
<category>IOS</category>
</categories>
<tags>
<tag>.a</tag>
</tags>
</entry>
<entry>
<title><![CDATA[创建cocopods私有库]]></title>
<url>%2F2019%2F01%2F18%2FcocopodKu%2F</url>
<content type="text"><![CDATA[通常我们项目中都有一些公共的组件需要抽离出来,减少依赖,今天跟大家介绍的就是怎么通过cocopods创建私有库,引入到项目中供大家使用。一 首先要明白两个概念:1.code repository是代码库。2.spec repository是配置仓库,所有的配置按照包名、源地址,相关依赖的存放在这个仓库。这个仓库只用来存放podspec文件,不存放代码。二 创建cocopods仓库相关步骤:1.在本地创建lib仓库pod lib create podsDemoSdk1)相关目录结构如下:2)创建时候相关信息如下: 将本地仓库关联到远端git仓库 我们用的是gitlab 创建的git仓库1)git add . #不但可以[跟单]文件,还可以跟通配符,更可以跟目录。一个点就把当前目录下所有未追踪的文件全部add了,注意空格2)git commit -m “注释” #把文件提交到仓库3)git remote add origin 远程仓库地址 #本地关联远程仓库4)git push -u origin master #把本地库的所有内容推送到远程库上(第一次需要加-u,后面就不用加了) 将相关sdk 代码放在 podsDemoSdk/Classes 目录下4.配置相关spec 文件配置相关远程仓库地址和相关内容,按着图中格式配就行了。 验证podspec的有效性,打开终端 cd 到podsDemoSdk的目录中接着运行pod lib lint如果有警告,会导致无法通过,需要添加–allow-warnings如果使用了c函数相关的,需要添加–use-libraries显示pass 字眼 验证通过后,把代码提交到仓库即可5.把代码提交到仓库即可git add -Agit commit -m “add pod files”git remote add origin 远程仓库 //连接远程github项目git tag ‘0.1.0’ //这里的版本号注意要和podspec文件中的版本号统一git push –tags //将本地tag更新到github项目上去git push origin master //将本地项目更新到github项目上去 创建一个spec私有仓库现在GitLab上面创建一个私有仓库,用来存放私有依赖代码库的配置在终端执行命令:pod repo add podsDemoSpecs spec仓库地址 也就是在~/.cocoapods/repo目录下添加了一个以你的私有repo为名的文件夹 现在为止,我们已经在本地得到我们自己的私有仓库 podsDemoSpecs ,这是一个空的仓库 7.关联代码库和配置仓库pod repo push podsDemoSpecs podsDemoSdk.podspec –use-libraries –allow-warnings 至此仓库已经创建完成 三,下面是在项目中的应用,直接在podfile文件中配置相关信息就好,pod install即可 谢谢,如果不足,请指正谢谢!]]></content>
<categories>
<category>IOS</category>
</categories>
<tags>
<tag>组件化</tag>
</tags>
</entry>
<entry>
<title><![CDATA[结合fastlane 组件进行自动化测试]]></title>
<url>%2F2018%2F12%2F28%2Ffastlane-test%2F</url>
<content type="text"><![CDATA[1.Xcode创建一个含有Unit Tests的项目1)单元测试target设置info中添加tests,options中勾选Gather coverage框。xcode9.2和xcode9.3位置不太一样,下面的图片是xcode9.3的配置 这个是测覆盖率用的2.安装fastlane1)sudo gem install fastlane -NV或是brew cask install fastlane我这里使用gem安装的2)安装完了执行fastlane –version,确认下是否安装完成和当前使用的版本号。、>3.初始化Fastlane1)cd到你的项目目录执行2)fastlane init初始化成功后会在当前工程目录生成一个fastlane文件夹Appfile主要存放App的apple_id team_id app_identifier等信息Deliverfile中为发布的配置信息,一般情况用不到。Fastfile是我们最应该关注的文件,也是我们的工作文件。4) 添加组件fastlane add_plugin xcpretty_report 用于生成测试报告5)配置Fastfile相关信息`default_platform(:ios) platform :ios do desc “自动化测试” lane :unittest doUI.message(“start xcodebuild”)xcodebuild(test: true,scheme: “quickDemo”,workspace: “quickDemo.xcworkspace”,destination: “platform=iOS Simulator,name=iPhone XR,OS=12.1”,)UI.message(“success xcodebuild”) xcpretty_report(buildlog_path: ‘fastlane’,output_path: ‘fastlane/reports’,use_json_formatter: true) gym(xcpretty_report_html:”tests.html”,)UI.message(“start xcov”)xcov(scheme: “quickDemo”,workspace: “quickDemo.xcworkspace”,html_report: “true”,json_report: “true”,output_directory:”quickDemoesss”)UI.message(“success xcov”) desc “读取覆盖率”file = File.read(File.expand_path(“/Users/edz/Desktop/quickDemo/quickDemoesss/report.json”))if filedata = JSON.parse(file)UI.message(data)UI.message(data[“coverage”])elseUI.error(“Unable to open file!”)returnendend end` 6 执行 fastlane unittest]]></content>
<categories>
<category>IOS</category>
</categories>
<tags>
<tag>自动化</tag>
</tags>
</entry>
<entry>
<title><![CDATA[xcode10坑】用xcode10 打包上传到AppStore,iOS9 Crash]]></title>
<url>%2F2018%2F11%2F28%2Fxcode10%2F</url>
<content type="text"><![CDATA[用Xcode10 打包上传到AppStore,iOS9系统的机器频繁 Crash; 还是老老实实用Xcode 9.4.1打包吧,坑死了。xcode10.1会解决这个问题。]]></content>
<categories>
<category>IOS</category>
</categories>
<tags>
<tag>someBug</tag>
</tags>
</entry>
<entry>
<title><![CDATA[multiple commands produce '' 日常error记载]]></title>
<url>%2F2018%2F10%2F28%2Fmuitiple-error%2F</url>
<content type="text"><![CDATA[下载别人demo 或者日常写项目中会遇到类似如下的bug: 这个时候可以通过如下方式,删除info.plist 然后command+R 允许即可 完美:]]></content>
<categories>
<category>IOS</category>
</categories>
<tags>
<tag>someBug</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Xcode 10 打包导出时报错Failed to verify bitcode in]]></title>
<url>%2F2018%2F09%2F28%2FxcodeBug%2F</url>
<content type="text"><![CDATA[作为iOS开发者,新的开发工具正式发布时定然要及时更新,但不幸的是有好多坑。这是其中一个比较难遇见的坑,其他的在网上比较好找,就不一一列出了。当打包导出的时候,提示错误如下: Failed to verify bitcode in AipBase.framework/AipBase: error: Cannot extract bundle from /var/folders/n2/2hc63w0d555cdbpqxwmpy84w0000gn/T/XcodeDistPipeline.ujv/Root/Payload/DDGD.app/Frameworks/AipBase.framework/AipBase (i386) 方法一: 这是因为code 新的build System造成的,一个避免延误开发打包的方法展示给大家:进入xcode -file-workSpace settings : 选择 legacy build System 重新打包导出解决问题。 方法二:为了方便开发者调试,AipBase.framework合并了模拟器和真机架构,上线前,使用lipo工具移除相关架构即可,就可以解决这个问题,这个解决的比较彻底,建议用这个方法: cd lib 使用lipo -info 可以查看包含的架构lipo -info AipBase.framework/AipBase # Architectures in the fat file: AipBase are: i386 x86_64 armv7 armv7s arm64 # 移除x86_64, i386 lipo -remove x86_64 AipBase.framework/AipBase -o AipBase.framework/AipBase lipo -remove i386 AipBase.framework/AipBase -o AipBase.framework/AipBase lipo -remove x86_64 AipOcrSdk.framework/AipOcrSdk -o AipOcrSdk.framework/AipOcrSdk lipo -remove i386 AipOcrSdk.framework/AipOcrSdk -o AipOcrSdk.framework/AipOcrSdk # 再次查看 lipo -info AipBase.framework/AipBase # Architectures in the fat file: AipBase are: armv7 armv7s arm64]]></content>
<categories>
<category>IOS</category>
</categories>
<tags>
<tag>someBug</tag>
</tags>
</entry>
<entry>
<title><![CDATA[flex 盒子布局 自我总结]]></title>
<url>%2F2018%2F02%2F05%2Fflex-%E7%9B%92%E5%AD%90%E5%B8%83%E5%B1%80-%E8%87%AA%E6%88%91%E6%80%BB%E7%BB%93%2F</url>
<content type="text"><![CDATA[本篇仅限自我学习,参考阮一峰的flex布局http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html:一, flex-direction: 属性决定主轴的方向(即项目的排列方向) row(默认值):主轴为水平方向,起点在左端。 row-reverse:主轴为水平方向,起点在右端。 column:主轴为垂直方向,起点在上沿。 column-reverse:主轴为垂直方向,起点在下沿。二, flex-wrap :换不换行三,对齐方式 默认情况下row: justify-content 表示的是X 轴的 对齐方式 align-items 表示Y轴的对齐方式 align-content属性 (一般是有多个对齐的轴线的时候)属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。 如果设置flex-direaction:column justify-content Y 轴的 对齐方式 align-items 表示X轴的对齐方式 水平和垂直剧中或者水平剧中,垂直至底 需要设置两个轴: justify-content: center; align-items: center;align-self属性 属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性 四, flex :flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。flex-shrink属性 如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。flex-basis属性 项目占据的主轴空间 不会被其他的项目影响(它的默认值为auto),如果主尺寸不为 auto,则使用值采取主尺寸之值;如果也是 auto,则使用值为 content。 content:指根据该子元素的内容自动布局。有的用户代理没有实现取 content 值,等效的替代方案是 flex-basis 和主尺寸都取 auto。 百分比:根据其包含块(即伸缩父容器)的主尺寸计算。如果包含块的主尺寸未定义(即父容器的主尺寸取决于子元素),则计算结果和设为 auto 一样。 #####flex-grow 属性 flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。 如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。 (1).当 flex 取值为一个非负数字,则该数字为 flex-grow 值,flex-shrink 取 1,flex-basis 取 0%,如下是等同的:123456.item {flex: 1;}.item {flex-grow: 1; 的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)flex-shrink: 1; 默认为1,即如果空间不足,该项目将缩小。flex-basis: 0%; 项目占据的主轴空间 不会被其他的项目影响(它的默认值为auto)} #####(2)当 flex 取值为 none,则计算值为 0 0 auto,如下是等同的:123456.item {flex: none;}.item {flex-grow: 0;flex-shrink: 0;flex-basis: auto;} #####(3 )当 flex 取值为一个长度或百分比,则视为 flex-basis 值,flex-grow 取 1,flex-shrink 取 1,有如下等同情况(注意 0% 是一个百分比而不是一个非负数字):123456789101112.item-1 {flex: 0%;}.item-1 {flex-grow: 1;flex-shrink: 1;flex-basis: 0%;}.item-2 {flex: 24px;}.item-1 {flex-grow: 1;flex-shrink: 1;flex-basis: 24px;} #####(4 )当 flex 取值为两个非负数字,则分别视为 flex-grow 和 flex-shrink 的值,flex-basis 取 0%,如下是等同的:123456.item {flex: 2 3;}.item {flex-grow: 2;flex-shrink: 3;flex-basis: 0%;} #####(5)当 flex 取值为一个非负数字和一个长度或百分比,则分别视为 flex-grow 和 flex-basis 的值,flex-shrink 取 1,如下是等同的:123456.item {flex: 2333 3222px;}.item {flex-grow: 2333;flex-shrink: 1;flex-basis: 3222px;}]]></content>
<categories>
<category>前端</category>
</categories>
<tags>
<tag>flex</tag>
</tags>
</entry>
<entry>
<title><![CDATA[ionic3.7照相和多图片选择]]></title>
<url>%2F2017%2F08%2F21%2Fionic3-7%E7%85%A7%E7%9B%B8%E5%92%8C%E5%A4%9A%E5%9B%BE%E7%89%87%E9%80%89%E6%8B%A9%2F</url>
<content type="text"><![CDATA[做了ionic项目也有一段时间了,把之前做的笔记分享出来,仅供大家参考,一起学习、一起进步,我感觉学一门语言,就是去找实际的案列直接应用它,在实践中学习,今天介绍的是通过ionic UI组件ImagePicker、Camera进行照片和照相功能 1)首先你要想用这个组件必须要添加它,通过命令行npm install –save @ionic-native/camera 安装camera;通过命令行npm install –save @ionic-native/image-picker 安装image-picker,但是注意除了这个命令还要安装插件cordova plugin add https:/github.com/Telerik-Verified-Plugins/ImagePicker.git,这个命令需要git,所以要按照git,这里就不多说了。 2)安装完命令就可以撸代码了,通过ActionSheetController 弹出选择框 选择照片和相机,代码如下:12345678910111213141516171819202122232425let actionSheet = this.actionSheetCtrl.create({title: '',buttons: [{text: '拍照',handler: () => {this.getPhoto();console.log('拍照 clicked');}}, {text: '相册',handler: () => {this.getImage();console.log('相册 clicked');}}, {text: '取消',role: 'cancel',handler: () => {console.log('取消 clicked');}}]});actionSheet.present(); 3)多文件选择:代码如下:123456789101112131415161718192021let n = $('.uploadimg_list').children().length;const optionss= { maximumImagesCount:4-n};this.imagePicker.getPictures(optionss).then((results) => {this.imageArr.splice(0, this.imageArr.length);let resultsfor (let i = 0; i < results.length; i++) {this.imageArr.push(results[i]);let img_list = $('.uploadimg_list');for (let i = 0; i < this.imageArr.length; i++) {resultess = '<div class="img_wrap"><div class="close_btn"></div></div>';}img_list.append(resultess);sessionStorage.setItem('imgtxt_imgs', JSON.stringify(this.imageArr));}}, (err) => {alert( '未选择');}); 4)照相机:代码如下123456789101112131415161718const options: CameraOptions = {quality: 50,destinationType: this.cameras.DestinationType.DATA_URL,encodingType: this.cameras.EncodingType.JPEG,mediaType: this.cameras.MediaType.PICTURE}this.cameras.getPicture(options).then((imageData) => {//this.imageArr.splice(0, this.imageArr.length);let resultess;this.imageArr.push(imageData);let img_list = $('.uploadimg_list');resultess = '<div class="img_wrap"><div class="close_btn"></div></div>';img_list.append(resultess);sessionStorage.setItem('imgtxt_imgs', JSON.stringify(this.imageArr));}, (err) => {// Handle erroralert( '未选择');});]]></content>
<categories>
<category>ionic</category>
</categories>
</entry>
<entry>
<title><![CDATA[ionic ion-slide 高度问题]]></title>
<url>%2F2017%2F05%2F06%2Fionic-ion-slide-%E9%AB%98%E5%BA%A6%E9%97%AE%E9%A2%98%2F</url>
<content type="text"><![CDATA[用ion-slide封装滑动视图组件,进行滑动导航相关操作,每一个slide下都会放一个页面,每个页面的高度又是不一样的,这个时候使用ion-slide会出现一个问题,高度最高只能有屏幕那么高,如果你在有tab栏的情况下使用,高度只有屏幕高screen-height-tab高这么高,这样显然是不可以的。我们解决问题要主要结合调试工具,看看里边那个类影响了他的高度,光百度,谷歌还是不行的,重要的是学会调试,学会理解。首先我们可以先解决tab高度,让她屏幕这么高:12345.scroll-content{height: 100%;}``` 然后在slides标签中增加 style=”height:auto” <br>在ts文件中slide自适应高度 $(‘.slide-zoom’).css(‘height’,date.data.length * 200); <br>注意在没有内容时候还是要通过动态设置,将其设置成 $(‘.slide-zoom’).css(‘height’,100%);`以防出现问题,谢谢大家!]]></content>
<categories>
<category>ionic</category>
</categories>
</entry>
<entry>
<title><![CDATA[angular4跨域请求]]></title>
<url>%2F2017%2F04%2F16%2Fangular4%E8%B7%A8%E5%9F%9F%E8%AF%B7%E6%B1%82%2F</url>
<content type="text"><![CDATA[angular4和其他框架一样,运用网络请求的时候都会出现跨域的情况(跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制),出现跨域以后怎么解决呢,今天介绍一种angular4-JSONP解决跨越,下面县介绍一下jsonp: jsonp动态生成sript标签 ,src 指向地址:ajax请求受同源策略影响,不允许进行跨域请求,而script标签src属性中的链接却可以访问跨域的js脚本,利用这个特性,服务端不再返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。 进入正题直接看代码,首页在app.module.ts引入: imports: [ BrowserModule, HttpModule, RouterModule.forRoot(routes), IonicModule.forRoot(MyApp,{ tabsHideOnSubPages: 'true' //隐藏全部子页面tabs }) ], 在所需要的面引入http: import {Http, ResponseOptions,Headers,HttpModule,URLSearchParams,Jsonp} from "@angular/http"; 然后注入: constructor(public jsonp:Jsonp,public http:Http) {} 带参数的, 注意一定要引入 URLSearchParams,要不请求是失败的: let d1 = new URLSearchParams(); d1.set('key', 'value' ); d1.set('key', 'value' ); d1.set('key', ‘value’); d1.set('format', 'json'); d1.set('callback', 'JSONP_CALLBACK'); this.jsonp.get(url,{ search: d1 }) .subscribe((response) => { let res = response.json() console.log(res) }, (error) => { console.error(error); }); 下面这两个参数是必须引入的,如果不存在jsonp可以不加2 1. d1.set('format', 'json'); 2. d1.set('callback', 'JSONP_CALLBACK'); 今天就介绍到这,谢谢]]></content>
<categories>
<category>前端</category>
</categories>
</entry>
<entry>
<title><![CDATA[Angular4基本网络请求get、post方式]]></title>
<url>%2F2017%2F03%2F13%2FAngular4%E5%9F%BA%E6%9C%AC%E7%BD%91%E7%BB%9C%E8%AF%B7%E6%B1%82get%E3%80%81post%E6%96%B9%E5%BC%8F%2F</url>
<content type="text"><![CDATA[angular2的网络请求和4还是有很大区别的,写一个项目的话肯定会用到http服务,除非你都是静态页,这只是一个最基本的、深入的拓展即可,希望能够帮助大家吧,谢谢首先如果你想用这个服务、那么你需要在app.module.ts中引入如下:1234567891011121314151617181920212223242526272829imports: [BrowserModule,HttpModule,RouterModule.forRoot(routes),IonicModule.forRoot(MyApp,{tabsHideOnSubPages: 'true' //隐藏全部子页面tabs})],``` 在所需要的面引入http:``` import {Http, ResponseOptions,Headers,HttpModule,URLSearchParams} from "@angular/http";``` 然后注入:``` constructor(private http:Http) {}``` 不带参数的post``` this.http.post(randomUserUrl).map(res => res.json()).subscribe(function (data) {alert(JSON.stringify(data));},err =>{console.error('ERROR', err);}); 不带参数的get1234567this.http.get(randomUserUrl).map(res => res.json()) // (5).subscribe(data => {alert(JSON.stringify(data));},err =>{console.error('ERROR', err);}); 带参数的⚠️注意post与get传参数方式不一样!带参数的post, 注意一定要引入 URLSearchParams,要不请求是失败的: 12345678910let d1 = new URLSearchParams();d1.append('key', 'value' );d1.append('key', 'value' );d1.append('key', ‘value’);this.http.post(randomUserUrl,d1).map(res => res.json()).subscribe(function (data) {alert(JSON.stringify(data));}); 带参数的get 12345678910let dates ={放参数keyvalue};this.http.get(randomUserUrl,{params: dataes}).map(res => res.json()) // (5).subscribe(data => {alert(JSON.stringify(data));},err =>{console.error('ERROR', err);}); 今天就介绍到这,谢谢]]></content>
<categories>
<category>前端</category>
</categories>
</entry>
<entry>
<title><![CDATA[安装@angularcli的坑]]></title>
<url>%2F2017%2F01%2F06%2F%E5%AE%89%E8%A3%85-angularcli%E7%9A%84%E5%9D%91%2F</url>
<content type="text"><![CDATA[之前写了个ionic项目,总感觉angluar知识懂的太少,前段时间花了一段时间深入学习了一些angular4的知识,之前iOS的时候也没有发文章的习惯,都是放在笔记本中了,老是享受别人的分享,自己也不自量力把学习和工作中遇见的坑分享一下,仅供学习,不对的地方欢迎改正。 1.之前用ionic写项目的时候用的还是npm3.00,node6.1,所以一开始安装@angularcli的时候老是报错,因为@angular需要nmp3.00 和node6.9以上才可以,而刚才node6配置的是angularcli,angularcli与@angluarcli是不一样的,旧版不能使用aot编译,且后期升级会有一堆麻烦, 2.错误❌You cannot use the new command inside an angular-cli project 这个时候需要找到node_modules/下的package.json,删除掉,重新ng new project 就可以了 3.如果报的gyp ERR! System Darwin 15.6.0 提示你没有权限,你可以尝试用1).sudo npm uninstall -g @angular/cli 先删除 2).sudo chown -R whoami /usr/local 3).sudo npm i -g npm 更新npm 4).npm install 5),sudo npm install -g @angular/cli 总的来说还是比较简单的,这里就不说具体的步骤,因为官网都有,谢谢查看。一起进步。]]></content>
<categories>
<category>前端</category>
</categories>
</entry>
<entry>
<title><![CDATA[Angular4]]></title>
<url>%2F2017%2F01%2F06%2FAngular4%2F</url>
<content type="text"><![CDATA[Angular 是由谷歌开发与维护一个开发跨平台应用程序的框架,同时适用于各种平台 1.Angular 与 AngularJS 有什么区别 不再有Controller和 Scope 更好的组件化及代码复用 更好的移动端支持 引入了 RxJS 与 Observable 引入了 Zone.js,提供更加智能的变化检测 全新的命令行工具@angular cli 服务器渲染 2.Angular 与vue vue只关注web, 是个人主导的而angular的背后是谷歌团队 3.Angular 吸收了angular js reactjs的优点 4.下面是angular 的基本架构,angular就是有许多组件组成的树形结构]]></content>
<categories>
<category>前端</category>
</categories>
</entry>
<entry>
<title><![CDATA[Hello World]]></title>
<url>%2F2016%2F10%2F28%2Fhello-world%2F</url>
<content type="text"><![CDATA[Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub. Quick StartCreate a new post1$ hexo new "My New Post" More info: Writing Run server1$ hexo server More info: Server Generate static files1$ hexo generate More info: Generating Deploy to remote sites1$ hexo deploy More info: Deployment]]></content>
<categories>
<category>hexo</category>
</categories>
</entry>
</search>