利他才能利己


  • 首页

  • 标签

  • 归档

  • 搜索

PHP 开发准备

发表于 2017-02-02 | 分类于 Server |

注意:这篇文章是基于 Homebrew 安装 php5.6 以及 nginx 和 mysql 的介绍,安装高版本的 php 请绕行。

简介

亲自实践在 MacOS 上面安装 PHP5.6+MySQL+Nginx.

将自己遇到的问题和对应的解决方案, 分享出来, 希望能帮到你.

MacOS 上面搭建 PHP 开发环境, 使用 Homebrew 来安装对应的开发套件, 就更加简单了.

这篇博客的目的就是安装 PHP 开发环境, 并将第一个 PHP 程序部署在 Nginx 上面.

如果在安装和使用过程中遇到问题, 可以查看这篇博客: Mac PHP 安装遇到的问题.

下面开始介绍具体的安装步骤.

一. 安装 Homebrew

这个大家可以自行访问 Homebrew 了解, 这里不再涉及具体的安装过程和方法.

二. 安装 php56

1.加入官方源

1
2
3
brew tap homebrew/dupes
brew tap homebrew/versions
brew tap homebrew/php

2.安装 PHP

默认安装会运行在 Apache 下.
而我们要使它运行在 PHP-fpm 下,所以要增加参数:

1
--with-fpm --without-apache

查看所有安装参数可以输入:

1
brew option php56

进行查看,参考安装指令:

1
2
3
4
5
6
7
8
9
10
11
12
brew install php56 \
--without-snmp \
--without-apache \
--with-debug \
--with-fpm \
--with-intl \
--with-homebrew-curl \
--with-homebrew-libxslt \
--with-homebrew-openssl \
--with-imap \
--with-mysql \
--with-tidy

这里使用了下面的选项:

1
with-homebrew-curl

我试过不带此选项, 安装 PHP56 会失败, 找不到 curl.

安装成功后, 可以查看版本信息:

1
2
php -v
php-fpm -v

此时看到是的系统自带的版本.

下面一步是增加环境变量, 完成后在看版本信息, 即可.

3.配置 PHP 环境变量

配置环境变量的目的是要使用 brew 安装的 PHP 和 PHP-fpm, 不使用 MacOS 自带的 PHP 版本.

/usr/local/sbin/ 下面是我们 brew 安装的 PHP, 其实他是一个软连接指向:
/usr/local/Cellar/php56/5.6.27_4/sbin

/usr/local/bin/ 下面也是 brew 安装的 PHP, 指向:
/usr/local/Cellar/php56/5.6.27_4/bin

vim ~/.bash_profile 增加

1
export PATH="/usr/local/sbin:$PATH"

使其立即生效, 执行

1
source ~/.bash_profile

或者重启终端.

如果想看系统的 PHP 版本可以这样:

1
/usr/bin/php -v

4.配置 php-fpm

1
sudo cp /private/etc/php-fpm.conf.default /private/etc/php-fpm.conf
1
sudo vi /private/etc/php-fpm.conf

找到 error_log 项,添加下面配置:

1
2
error_log = /usr/local/var/log/php-fpm.log
pid = /usr/local/var/run/php-fpm.pid

否则会报:

1
FPM initialization failed

三. 安装 nginx

1
brew install nginx

创建文件

1
2
3
4
5
mkdir -p /usr/local/var/logs/nginx
mkdir -p /usr/local/etc/nginx/sites-available
mkdir -p /usr/local/etc/nginx/sites-enabled
mkdir -p /usr/local/etc/nginx/conf.d
mkdir -p /usr/local/etc/nginx/ssl
1
2
3
4
5
6
7
sudo mkdir -p /var/www
sudo chown :staff /var/www
sudo chmod 775 /var/www
vi /var/www/info.php
vi /var/www/index.html
vi /var/www/403.html
vi /var/www/404.html

改变 nginx.conf 配置文件

该配置文件在 /usr/local/etc/nginx/nginx.conf 下面.

我的配置:

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
worker_processes  1;

error_log /usr/local/etc/nginx/logs/error.log debug;
pid /usr/local/var/run/nginx.pid;

events {
worker_connections 256;
}

http {
include mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /usr/local/etc/nginx/logs/access.log main;

sendfile on;

keepalive_timeout 65;

index index.html index.php;

include /usr/local/etc/nginx/sites-enabled/*;
include /usr/local/etc/nginx/conf.d/*;
server {
listen 8080;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root ~/projs/phpdev/nginx/nginx_sites/; #web的根目录
index index.php index.html index.htm; #加index.php
}
}
}

注意:

1
2
3
4
location / {
root ~/projs/phpdev/nginx/nginx_sites/; #web的根目录
index index.php index.html index.htm; #加index.php
}

配置了我的 web 目录和支持的文件.

四. 运行 PHP

创建 index.php

启动 PHP-fpm

1
sudo php-fpm

或者以守护进程的方式来启动 PHP-fpm

1
sudo php-fpm -D

启动 Nginx

1
sudo nginx

编辑 index.php

在 web 目录(我配置的) /Users/mark/workspace/mzProjs/phpdev/nginx/nginx_sites/ 新建文件 index.php.

index.php 里面可以编写代码:

1
2
3
4
5
6
7
8
9
10
<!-- lang: php -->
<!-- ~/nginx_sites/index.php -->
<?php
echo "Hello PHP";
echo "</br>";

echo "学习 php";
echo "</br>";
echo phpinfo();
?>

打开浏览器, 你会看到下面的页面:
1

也可以在该目录下创建其他 php 文件, 如 mark.php 文件.

浏览器中输入:
http://localhost:8080/mark.php 可以执行相对应的文件.

这里的 mark.php 是自己新建的 php 文件.

五. 安装 MySQL

1
brew install mysql

等待安装成功后,直接启动和连接数据库。

  • 启动 mysql
1
mysql.server start
  • 连接 mysql
1
mysql -u root -p

过年回家这几天

发表于 2017-01-31 | 分类于 随笔 |

从放假回家到现在已经一个多星期了, 感触颇多.

主要有以下几个感触:

1.健康最重要.
2.坚持做好一件事情.
3.感恩.

1

健康

前两年回家, 还能见着很多长辈, 互相嘘寒问暖, 家长里短的闲聊, 如今有些已离我远去.

无情的疾病夺走了尚未花甲的他们, 让人不禁感叹生命的脆弱.

我小的时候, 很喜欢和长辈们聊天.

主要是他们讲, 我做一个小小的听众, 觉得他们懂得特别多, 从天文到地里, 从文学到艺术, 讲的有声有色.
每逢夏季, 我都会搬着小板凳, 在屋前的老树下, 纠缠他们, 逼着嚷着让他们给我讲故事, 甭提有多高兴.

如今, 老树犹在, 他们已不在人世.睹物思人.

农村大部分人, 不太关注自己的健康, 唯一衡量自己身体状况的标准就是 米饭馒头能吃多少.

很多人, 明明已经感觉到身体不适, 也不愿意去医院做检查, 就这样日积月累成疾.
等实在忍受不了才去医院检查, 为时已晚.

平时不注意自己的身体, 身体早晚都会让你注意.

无论平时工作再忙, 也要坚持锻炼, 没有健康的体魄, 其他的都是扯淡.

坚持

农村这几年鼓励年轻人在家创业, 搞养殖. 有很多人放弃了打工, 回家拿着补贴开始有模有样的创业.

前几年回老家, 看到各种搞养殖的, 有养鸡养鸭养鹅的, 有养羊养猪养牛的, 如雨后春笋, 遍地开花.

但是今年回家, 看到很多荒凉的房子, 无人问津.

我问过几个小伙子(之前在家搞养殖的人, 最后放弃了的).他们跟我说的基本都一样, 太累了, 收益慢!
搞养殖, 的确很累, 也很枯燥无味, 每天和这些不会说话的动物们待在一起, 喂它们吃喝, 管他们温饱, 实在乏味.

另外有两个年轻人, 从开始养殖到现在已经坚持五六年了, 搞得风生水起, 家里盖起了楼房, 取了巧媳妇, 生了胖小子, 一家人其乐融融.
他们跟我说的基本一样, 只要坚持, 就有收获!

这两个坚持下来的年轻人, 他们相信自己能够把这份事业做好, 他们把别人眼中的脏活累活当做一种快乐, 一种享受!

刚开始, 很艰难, 他们也想过放弃, 但是又舍不得这几年的付出, 于是就坚持下来了, 并且收获了不少意想不到的知识, 不管是物质上还是精神上都得到了满足.

世上, 没有一帆风顺的事业.

只要自己喜欢, 感兴趣的行业, 就值得你去坚持.
如果你从内心都不感兴趣, 趁早放弃, 因为你很难坚持下来.

想投机取巧的成就一份事业, 只有神话故事里有吧!

不经一番寒彻骨, 哪得梅花扑鼻香!

感恩

小的时候, 家里很拮据, 我能够把大学念完, 简直就是天意.

父母永远只会对我说一句话, 只要你想上学, 我们就支持到底.

我知道家里的经济情况, 所以在学习上也是不遗余力, 每次放学除了帮爸爸妈妈干农活, 就是完成家庭作业, 练字背书.

那个时候, 不知道哪来的狠劲, 即使是寒冬腊月, 也要坚持写作业, 即使是手都冻肿了, 也要练字.

当我接到重点高中通知书的那天, 父亲高兴的合不拢嘴, 心理充满了骄傲.

我能感觉到……

然而考上高中, 接下来就是凑钱交学费, 隔壁有个伯伯, 他说学费不够, 算他的.
那个时候, 大家家里都不宽裕, 能借钱给你的, 简直就是大恩人.
一直到现在, 我都很感激他, 每年过年回家, 我都会给伯伯买点礼物, 给个红包, 陪他聊聊天.他还开玩笑的说, 当年自己的投资, 算是有了回报了.

这辈子, 我们最应该感谢的是我们自己的父母, 养育我们成人, 送我们读书上学. 过年回家, 要多陪陪他们, 珍惜和他们在一起的每一刻.

学习杂谈

发表于 2017-01-27 | 分类于 随笔 |

今天是中国传统节日, 大年三十, 祝大家新年快乐, 身体健康, 幸福美满.

引子

最近无论是朋友还是同事或者博友, 都问过我关于学习方面的事情.

探讨的问题大概分为如下几种:

怎么有效的学习新知识?
怎么快速掌握新知识?
是否有必要每天学习?
如何坚持学习?
谈到关于学习的话题, 我也不是什么专家, 更不是心理咨询师, 只是谈谈个人的一些看法和经历, 希望能给大家带来一点点的帮助.

不要只是嘴上说 我感兴趣, 如果没有驱动和目标, 兴趣永远都只是兴趣.

你为什么学习它

学习知识之前, 问问自己为什么要学它? 大部分人学习新东西都是为了工作或者为了更好的工作或者为了转行或者其他目的, 也有一部分人是为了兴趣爱好.

这里我只谈为了工作而去学习新知识的内容, 其他方面的我自己也没有什么心得体会, 不能乱说.

既然为了工作或者更好的工作来学习, 那么我们就明确了目标, 如果你已经有了目标, 恭喜你, 你即将成功了.

有一些人说, 我学习它, 这个东西不一定哪天就有用了, 我怕将来失业.
这中担心不是在杞人忧天, 特别是在互联网的时代, 如果不学习很容易就落伍啦, 君担心完全在理!

但是, 当下你最应该考虑的是目前掌握的技能是否已经熟练了, 是否是能够独当一面了, 如果深学下去会不会更有前途? 如果是, 请你深入去学习, 不要太杞人忧天了!

在精钻一门学问的情况下, 可以扩大自己的知识面, 而不是 吃着碗里看着锅里 的, 要脚踏实地的大步向前.

坚持学习

上面的扯淡有点多啊.回正题.

既然搞清楚了为什么学习它, 接下来就是搞定它.

你需要有坚持学习的态度和行动, 不然一切都会成为云烟. 那么当初咬牙切齿的抱负, 结果都是冲动的惩罚.

学习新知识的前期是很累的, 但是只要你意志足够坚定, 一定可以克服种种困难.

记得当初接手一个二手项目, 项目也是足够复杂, 并且有很多引擎之前都没有用过, 上面领导逼得比较紧, 没办法, 只能将其拿下, 每天晚上挑灯夜战, 在 log 的海洋里遨游.

很快自己掌握了新的知识, 结合项目, 不断的去调试和总结, 最终按期完成需求, 回过头想想, 想要坚持做好一件事情, 除了自身的自我约束, 还需要外界环境的 倒逼.

当你坚持不住的时候, 问问自己, 是否已经到了极限, 如果感到累了, 适当的放松一下, 比如出去跑个步, 打个球或者找朋友叙叙旧.

适当的给自己一点压力, 事半功倍.

学习的渠道

刚开始学习新知识, 大家都渴望有一些大牛能够指导自己, 或者能够从前辈那里获取一些武林秘籍, 这些都是学习的渠道.

有些小伙伴在学习的过程中, 会遇到各种各样的困难, 比如在学习一门知识的时候, 发现竟然还需要学习另一门新知识, 真是日了狗了!
到这里, 可能有些人就会情不自禁的选择了放弃, 嘴上说还在学习, 其实心里已经疲倦.

还有一些初学者, 他们没有什么经验, 如果主动性再差点, 动辄遇到问题就问, 根本没有过思考, 哪怕是一点点的思考都没有.其实他们不是不想搞, 就怕搞错了.仅仅是因为怕, 就戛然而止了!
这种人, 确实可惜, 所以他们需要更多的指导和教育.这里提醒大家, 学习知识, 不要怕犯错, 大胆的去试错, 在错误中成长, 这样你才能有所收获.

记得以前为了安装 linux, 我把办公室的办公电脑都格式化了, 组长差点要开除我了, 现在想想虽然挨了骂, 但是挺值得.

现在互联网很发达, 想学习的东西基本网上都有, 你可以没有智商, 没有情商, 但是你一定要有 搜商 (搜索能力).
当你自己经过思考, 无法解决问题, 就去搜索相关的知识, 如果搜索也失败了, 再去请教别人, 这样你就可以从中收获意外的惊喜.

所以, 学习渠道的重要来源之一就是在互联网搜索, 培养自己的搜索能力很重要, 我建议大家使用谷歌浏览器, 然后使用 google 的搜索引擎, 搭建一套翻墙的 VPN, 这样你可以在知识的海洋里爽翻.

另外一个比较重要的学习渠道就是你认为的牛人, 向他们学习相关的学习方法, 问他们是怎么学习的, 然后结合自己的实际情况加以运用, 跟他们多交流.

对自己’狠’一些

我之前有个坏习惯, 喜欢晚上躺在床上看视频, 这些视频可能是优酷或者腾讯视频客户端的, 也有可能是新闻类的 app 来源的视频.
视频只要看起来, 时间就不受控制了.第二天早晨起床也很困难.

最后自己把视频类和新闻类 app 全部卸载掉了, 然后把目标转移到 stackoverflow 和 github 上面.
那里才是程序员的世界, 只有你想不到的, 没有做不到的.

为了学习新知识, 你需要对自己狠一点, 每天拿点时间出来总结和学习, 一个月一个季度一年下来, 你比别人都进步了很多.

养成一个好习惯, 终生受益.

iOS: 聊聊 UIWebView 缓存

发表于 2017-01-15 | 分类于 iOS |

前言

在开发项目过程中, 一些若交互的页面会使用 HTML 展示.

在 iOS 中, 使用 UIWebView 的频率还是比较高的.

今天跟大家聊聊 UIWebView 缓存相关的话题.

准备工作

我今天使用 Tomcat 来作为 web 容器, 在本机搭建一个 web 服务器, 然后使用 iPhone 访问该 web 页面, 展示和梳理 UIWebview 关于缓存的问题.

如果你对 Tomcat 还不熟悉, 希望你可以先去大概了解一下, 如何在 Mac os 上面安装和使用 Tomcat, 可以参考我的博文: [Mac 配置 Tomcat8].

Tomcat 是一个开放源代码、运行 servlet 和 JSP Web 应用软件的基于 Java 的 Web 应用软件容器.
Tomcat Server 是根据 servlet 和 JSP 规范执行的,因此可以说 Tomcat Server 实行了 Apache-Jakarta 规范,且比绝大多数商业应用软件服务器要好.
但是 Tomcat 对静态文件、高并发的处理比较弱.

写这篇文章的时候, 我使用的版本分别是 apache-tomcat-8.5.8, jdk1.8.

配置 Tomcat

修改 server.xml 文件

文件在 Tomcat 的根目录的 conf 目录下, 如我的文件在这个目录:

1
apache-tomcat-8.5.8/conf/server.xml

增加如下内容:

1
2
3
4
<Host name="<your local ip>" debug="0" appBase="<base dir>" unpackWARs="true" autoDeploy="true" xmlValidation="false"  xmlNamespaceAware="false">
<Context path="" docBase="<html file path>" debug="0" reloadable="true" crossContext="true"/>
<Logger className="org.apache.catalina.logger.FileLogger" directory="logs" prefix="tot_log." suffix=".txt" timestamp="true"/>
</Host>

注意:
1.将上述内容放到 </Host> 和 </Engine> 节点中间.
2.将 name="<your local ip>" 中的 改为你本机的 ip 地址.
查看本机的 ip 地址方法很简单:

1
ifconfig | grep "inet " | grep -v 127.0.0.1

3.将 appBase=”“ 中的 改为你的 web 目录.
4.将 docBase=”“ 中的 改为你的 html 目录.

我的配置如下(部分):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
	<Host name="localhost"  appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />
</Host>
<!--mark 配置静态网页. [BEGIN] -->
<Host name="192.168.1.103" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<Context path="" docBase="test" debug="0" reloadable="true" crossContext="true"/>
<Logger className="org.apache.catalina.logger.FileLogger" directory="logs" prefix="tot_log." suffix=".txt" timestamp="true"/>
</Host>
<!--mark 配置静态网页. [END] -->
</Engine>
</Service>
</Server>

搞定上面的配置, 接下来可以配置相关目录了.

在 Tomcat 的根目录有个文件夹 webapps, 在 webapps 目录下新建目录 test 即可.

构建 HTML 页面

在 test 目录, 新建一个 html 文件

1
touch test.html

文件内容如下:

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
 <p>
<em>Sample</em> text</p>
<p>
Now I input another line, with fancy<u><strong><em>styles</em></strong>
</u>.</p>
<p>
<em>Sample</em> text</p>
<p>
Now I input another line, with fancy <u><strong><em>styles</em></strong>
</u>.</p>
<p>
mark.zhang is itman.
</p>
<style>
.button {
background-color: #4CAF50;
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 86px;
margin: 50px 200px 100px 300px;
cursor: pointer;
border-radius: 15;
}
</style>
<p>
<button type="button" onclick="myFunction()" class="button">Try it</button>
</p>
<script>
function myFunction() {
alert("Blog: www.veryitman.com");
};
</script>

搭建完成后, 启动 Tomcat 服务器.

1
startup.sh

在浏览器里面通过 ip:port/test.html 的方式来访问该页面.

看到类似下面的效果即表示搭建成功:

1

客户端访问

客户端访问该页面, 使用 UIWebview 来请求(HTTP 协议)页面内容.

一般请求会使用下面的方法:

1
+ (instancetype)requestWithURL:(NSURL *)URL;

该方法的描述如下:

1
2
Creates and returns a URL request for a specified URL with default cache policy and timeout value.
The default cache policy is NSURLRequestUseProtocolCachePolicy and the default timeout interval is 60 seconds.

大概意思是使用的缓存策略是根据协议来的, 即 NSURLRequestUseProtocolCachePolicy. 超时时间默认是60s.

也就是说类似如下的请求:

1
2
NSURLRequest *urlReq = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.f];

如果协议支持缓存的话, UIWebview 请求到的数据就是缓存数据.该缓存是需要 WEB 服务器支持的.

这里我没有配置 Tomcat 的缓存.可以抓包看下:

2

后续博客会分别为大家介绍在 Tomcat 和 Nginx 配置缓存下, 客户端 UIWebview 请求的相关问题.

客户端显示页面效果:
2

ViewController 代码:

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
#import "ViewController.h"

static NSString * const H5Url = @"http://192.168.1.104:8080/test.html";

@interface ViewController () <UIWebViewDelegate>

@property (nonatomic, strong) UIWebView *webView;

@property (nonatomic, strong) UIButton *refBtn;

@end

@implementation ViewController

- (void)viewDidLoad
{
[super viewDidLoad];

_webView = [[UIWebView alloc] init];
CGSize boundsSize = self.view.bounds.size;
self.webView.frame = CGRectMake(0, 20, boundsSize.width, boundsSize.height);
self.webView.backgroundColor = [UIColor whiteColor];
self.webView.scrollView.showsHorizontalScrollIndicator = NO;
self.webView.scrollView.showsVerticalScrollIndicator = NO;
self.webView.scalesPageToFit = YES;
self.webView.delegate = self;
[self.view addSubview:self.webView];

UIButton *refreshBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[self.view addSubview:refreshBtn];
[refreshBtn addTarget:self action:@selector(onRefreshWebView) forControlEvents:UIControlEventTouchUpInside];
refreshBtn.backgroundColor = [UIColor redColor];
refreshBtn.layer.masksToBounds = YES;
refreshBtn.layer.cornerRadius = 5.f;
refreshBtn.frame = CGRectMake(50, 250, 200, 50);
[refreshBtn setTitle:@"刷新页面" forState:UIControlStateNormal];
_refBtn = refreshBtn;

[self loadDataUsingCache];
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
NSLog(@"didFailLoadWithError: %@", error);

[self hideLoading];
}

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
{
NSLog(@"shouldStartLoadWithRequest: %@", request);
return YES;
}

- (void)webViewDidStartLoad:(UIWebView *)webView
{
NSLog(@"webViewDidStartLoad");
}

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSLog(@"webViewDidFinishLoad");

[self hideLoading];
}

//刷新页面.
- (void)onRefreshWebView
{
// 方式1: 不使用缓存请求数据
//[self loadDataNoUsingCache];

// 方式2: 清除 NSCache 缓存, 再请求数据
[self clearAllCache];
[self loadDataUsingCache];
}

- (void)loadDataUsingCache
{
[self showLoading];

NSURL *url = [NSURL URLWithString:H5Url];

NSURLRequest *urlReq = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReturnCacheDataDontLoad
timeoutInterval:10.f];

[self.webView loadRequest:urlReq];
}

- (void)loadDataWithProtocol
{
[self showLoading];

NSURL *url = [NSURL URLWithString:H5Url];

[NSURLRequest requestWithURL:url];

NSURLRequest *urlReq = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.f];

[self.webView loadRequest:urlReq];
}

- (void)loadDataNoUsingCache
{
[self showLoading];

NSURL *url = [NSURL URLWithString:H5Url];
NSURLRequest *urlReq = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:20.0];
[self.webView loadRequest:urlReq];
}

- (void)clearAllCache
{
// remove cache rsp
[[NSURLCache sharedURLCache] removeAllCachedResponses];

[[NSURLCache sharedURLCache] setDiskCapacity:0];
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
}

- (void)showLoading
{
[self.refBtn setTitle:@"刷新中..." forState:UIControlStateNormal];
}

- (void)hideLoading
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.refBtn setTitle:@"刷新页面" forState:UIControlStateNormal];
});
}
@end

这里注意下面的 三个方法 :

1
2
3
4
5
6
7
8
9
// 使用缓存数据, 如果有缓存的话
// 使用这个方法, 改变 HTML 或者 JS 代码
// 页面不会拉取最新数据, 还是使用之前请求到的数据.
// 除非重新刷新
- (void)loadDataUsingCache;
// 使用协议缓存, 需要 web 服务器支持.
- (void)loadDataWithProtocol;
// 不使用缓存, 加载数据
- (void)loadDataNoUsingCache;

另外, 刷新 UIWebview 的方式如下, 有 两种方式 来刷新页面:

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 刷新页面.
*/
- (void)onRefreshWebView
{
// 方式1: 不使用缓存请求数据
//[self loadDataNoUsingCache];

// 方式2: 清除 NSCache 缓存, 再请求数据
[self clearAllCache];
[self loadDataUsingCache];
}

这种刷新方式, 会重新加载数据.
但是不适合多层级的 HTML 页面, 比如你的 HTML 页面有很多层, 想刷新当前页面, 可以使用下面的方式:

1
2
// 重新加载当前页面
[self.webView reload];

附加

查看本机 IP 的 shell

1
2
#!/bin/sh
ifconfig | grep "inet " | grep -v 127.0.0.1

停止 Tomcat 的运行

1
shutdown.sh

f8app

发表于 2017-01-01 | 分类于 ReactNative |

本文主要探讨的是如何编译和运行 f8app.

介绍

f8app 是 Facebook 开源的, 基于 React Native 开发的一款 App.

代码基本都是 js 的, 很少有原生的代码.

f8app 是借鉴和学习 React Native 的上好资料.

原文介绍:

This is the entire source code of the official F8 app of 2016, available on Google Play and the App Store.

项目开源地址: Github

编译运行

环境要求

  • 安装和配置了 React Native 开发环境.
  • Xcode 7.3 +
  • CocoaPods (only for iOS) 1.0+
  • MongoDB (needed to run Parse Server locally)

源码构建

下载源码

1
git clone https://github.com/fbsamples/f8app.git

下载完成后, 进入下载的 f8app 目录

1
2
cd f8app
npm install

如果是 iOS 的话, 需要进入 iOS 目录执行 pod install

1
2
cd ios
pod install

在项目 f8app 目录下运行:

1
npm start

打开浏览器输入地址 http://localhost:8080, 可以看到 graphql 的界面.

安装 MongoDB

使用 Homebrew 来安装.

1
brew install mongodb

导入数据

导入例子数据.

注意:
在源码的路径即 ~/yourpath/f8app 下面执行, 下面操作没有特殊说明都是在源码根目录下面操作.
你可以多开几个终端端口来进行操作.

1
npm run import-data

导入例子数据, 会报下面的 错误:

1
2
3
4
5
6
error: Uncaught internal server error. { [MongoError: connect ECONNREFUSED 127.0.0.1:27017]
name: 'MongoError',
message: 'connect ECONNREFUSED 127.0.0.1:27017' } Error: connect ECONNREFUSED 127.0.0.1:27017
at Object.exports._errnoException (util.js:893:11)
at exports._exceptionWithHostPort (util.js:916:20)
at TCPConnectWrap.afterConnect as oncomplete

需要安装 mongodb-runner

安装方法如下:

1
sudo npm install -g parse-server mongodb-runner

运行 mongodb-runner:

1
mongodb-runner start

这里执行完毕后, 需要等待一会.

你会看到如下信息:

1
Starting a MongoDB deployment to test against...

上面运行结束后, 你可以查看 MongoDB 是否在运行:

1
lsof -iTCP:27017 -sTCP:LISTEN

会显示当前正在运行的信息:

1
2
COMMAND   PID USER   FD   TYPE             DEVICE    SIZE/OFF  NODE  NAME
mongod 86824 mark 7u IPv4 0x91959c43a65644ed 0t0 TCP *:27017 (LISTEN)

停止 mongodb 运行的方式如下:

1
mongodb-runner stop

查看数据

Parse Dashboard

GraphiQL

启动 react-native

1
react-native start

运行 f8app

Android:

1
2
3
react-native run-android
adb reverse tcp:8081 tcp:8081 # required to ensure the Android app can
adb reverse tcp:8080 tcp:8080 # access the Packager and GraphQL server

iOS:

1
react-native run-ios

如果出现红色背景的 error 提示, 可以不管, 直接 Dismiss 即可.

然后可以看到如下界面:

1

问题

1.在运行后关闭登录按钮, 报错:

1
AppEventsLogger.logEvent

解决方案:

在 /js/store/track.js 文件的第 43 行, 注释掉 log, 如下:

1
2
3
case 'SKIPPED_LOGIN':
//AppEventsLogger.logEvent('Skip login', 1);
break;

在模拟器上面重新 Reload 即可.

再见 2016

发表于 2016-12-31 | 分类于 随笔 |

今天是2016年的最后一天,正好赶上放假,给自己的这一年做个小结。

2016,继续做项目,作为一名软件工程师,不停地在学习。

2016,学习到了很多关于产品和运营相关的知识。知道了 倒逼 的作用.

2016,读了20本非技术类书籍,养成了读书的习惯,并把读书的好处讲给身边的人听。

2016,开始减肥,注意锻炼身体,几乎每周都有一次从公司到家的步行,一次篮球或者跑步运动。

2016,购买了域名,建立了自己的 博客网站。

2016,儿子大了一岁,自己老了一岁,家庭依旧幸福着。渐渐地理解了做父亲的责任。

2016,对自己影响最大的几句话,分享给大家:

1. 技术要给产品提供最大的自由度.

2. 不要轻易的说 NO.

3. 要不断的让自己值钱, 而不是简单的为了金钱而跳槽.

4. 不要总是抱怨你的产品设计是狗屎, 学会和产品沟通更优的方案.

5. 关注细节, 把产品做好.

6. 多关注别人的优点.

7. 让对方把话说完.

8. 多看书, 多思考.

感谢所有陪伴和支持我的朋友,同事,亲人!

祝愿所有人2017幸福、健康、快乐!

Mac 配置 Tomcat8

发表于 2016-11-26 | 分类于 Server |

Tomcat 简介

Tomcat 是一个 Web 服务器.

Web 服务器是指为特定组件提供服务的一个标准化的运行时的环境.
可为组件提供事务处理, 数据访问, 安全性和持久性等服务.

Tomcat 是免费且开源的, 他是 Apache 软件基金会 Jakarta 项目中的其中一个子项目.由 Apache, Sun 和其他一些公司及个人共同开发完成.

Tomcat 也是使用最为广泛的 JSP 服务器.

JSP 是 Java Server Pages 的简称, 是在传统的 HTML 文件中插入 Java 程序段和 JSP 标记的一种动态网页技术.

下载 Tomcat

前往 这里 可以下载 Tomcat.

我目前安装的是 8.5.8 版本的.

1

安装

先安装 JDK, 安装教程可以参考 Mac 配置 JDK1.8 这篇文章.

解压下载的 tar.gz 即可.

最好解压到自己的工作目录, 如:

1
~/workspace/developr/

配置环境变量

编辑 /etc/profile 文件

1
sudo vim /etc/profile

添加如下变量:

1
2
3
4
5
JRE_HOME=$JAVA_HOME
TOMCAT_HOME=/Users/mark/developer/apache/apache-tomcat-8.5.8
PATH=$JAVA_HOME/bin:$TOMCAT_HOME/bin:$PATH
export JRE_HOME
export PATH

其中的 JAVA_HOME 是 Mac 配置 JDK1.8 这篇文章里面设置的 JDK 的环境变量.

配置环境变量的目的, 可以让我们方便的使用 Tomcat 的命令.

检验安装是否成功

使 /etc/profile 配置文件立即生效.

1
source /etc/profile

如果没有生效, 重启终端即可.

开启 Tomcat 服务, 执行下面的命令:

1
startup.sh

该命令在 Tomcat 的安装目录的 bin 目录下面.

执行后, 可以看到:

1
2
3
4
5
6
Using CATALINA_BASE:   /Users/mark/developer/apache/apache-tomcat-8.5.8
Using CATALINA_HOME: /Users/mark/developer/apache/apache-tomcat-8.5.8
Using CATALINA_TMPDIR: /Users/mark/developer/apache/apache-tomcat-8.5.8/temp
Using JRE_HOME: /Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home
Using CLASSPATH: /Users/mark/developer/apache/apache-tomcat-8.5.8/bin/bootstrap.jar:/Users/mark/developer/apache/apache-tomcat-8.5.8/bin/tomcat-juli.jar
Tomcat started.

在浏览器里面打开: http://localhost:8080/

即可看到一只可爱的 Tom 猫.

执行 shutdown.sh 可以关闭 Tomcat.

Mac 安装和使用 infer

发表于 2016-11-26 | 分类于 MacOS |

介绍

infer 是 Facebook 开源的一款代码静态检查工具, 源码可以在 Github 上面获取.

支持 Java/C/OC 等语言, 支持 Gradle, Buck, Maven, Xcodebuild, Make 等.

我一般用来分析 iOS 和 Android 工程.

可以在 这里 查看 Start.

安装 infer

只要你用 Homebrew, mac 下安装 infer 很简单:

1
2
brew update
brew install infer

在早期版本, infer 不支持 brew 安装. 安装起来各种问题, 现在 infer 支持了 brew 安装, 很方便.

这里我使用的 infer 版本是 0.9.4.

安装成功后, 可以查看安装版本:

1
infer -version

可以看到如下信息:

1
2
3
4
5
Infer version v0.9.4
Copyright 2009 - present Facebook. All Rights Reserved.
Mac:public mark$ infer --version
Infer version v0.9.4
Copyright 2009 - present Facebook. All Rights Reserved.

这里有个问题, 有时候 brew 无法更新最新的 infer, 我目前的解决方案是先卸载之前安装的 infer, 然后再重新安装.

卸载 infer

1
brew uninstall infer

安装 xcpretty

xcpretty 是一款格式化 xcodebuild 输出结果的工具.

1
2
3
4
5
6
▸ Building X/N [(Release)]
▸ Check Dependencies
▸ Copying Info.plist
▸ Running script '[CP] Check Pods Manifest.lock'
▸ Running script 'Replace PaySdk'
▸ Compiling User.m

从0.9.4版本后, infer 默认使用了 xcpretty.

可以使用 gem 安装 xcpretty 工具:

1
gem install xcpretty

如果没有安装成功, 或者提示权限不够, 那就这样折腾:

1
sudo gem install xcpretty

想了解更多关于 xcpretty 的使用可以去 github.

使用 infer

iOS 项目使用 infer

infer 的文档写的也较全面.

可以在 这里 查看使用方法.

1.分析 Cocoapods 项目

1
infer -- xcodebuild -workspace N.xcworkspace -scheme NSchema

其中 N.xcworkspace 是你的 workspace 名称, NSchema 是你需要检查的 Schema 名称.

2.分析 .xcodeproj

1
infer -- xcodebuild -target targetName -configuration Debug -sdk iphonesimulator

其中 targetName 是项目的 target 名称, 必须指定.

分析成功后, infer 会有输出报告.

该报告在你的项目目录下, 名称是 infer-out.

bug.txt 是以文本方式输出的 issue 文档.
另外还有 csv 格式的 issue 文档.

Android Gradle 工程使用 infer

1
2
gradle clean
infer -- gradle build

其他用法

infer 还有很多高级的用法, 比如可以增量检查.

增量检查的功能依赖于你的编译器是否支持.

infer 增量检查的选项是 –reactive.

之前的版本是 –incremental 选项.
自从 v0.8.0 版本后使用了 –reactive 选项.

可以这样来进行增量检查:

1
infer --reactive -- xcodebuild -workspace N.xcworkspace -scheme NSchema

infer 还有很多高级用法, 可以在 Advanced usage 中去查阅和使用.

再使用过程中, 随着 MacOS, Xcode 的升级, infer 会面临更多的挑战, 如果遇到问题, 第一时间去 GitHub 上面提 issue.

Mac 配置 JDK1.8

发表于 2016-11-26 | 分类于 Java |

下载 JDK

在 这里下载 jdk.

下载版本是 1.8u112, 信息如下:

1

安装 JDK

下载完成后, 直接双击安装即可.

配置 Path

成功安装后, 目录
/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/ 就会存在.

编辑 /etc/profile 文件:

1
sudo vim /etc/profile

添加如下代码:

1
2
3
4
5
6
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME
export CLASSPATH
export PATH

保存文件.

使这个文件立即生效.可以 source 一下

1
source /etc/profile

检验

执行下面命令来检验 jdk 是否安装成功.

1
java -version

输出如下信息, 标示配置 JDK 成功.

1
2
3
java version “1.8.0_112”
Java(TM) SE Runtime Environment (build 1.8.0_112-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b16, mixed mode)

扫码关注,你我就各多一个朋友~

GameDevelopment: 与 Cocos2d 的再相逢

发表于 2016-11-12 | 分类于 Game |

认识 Cocos2d

相信很多人听说过 cocos2d-x 这个引擎, 但听过 cocos2d-objc 的人应该不多.

cocos2d-objc 是 cocos 系列的 objective-c 版本.
开发语言是 OC.在 iOS 上面使用该版本的引擎, 基本是无缝连接(写的没有什么障碍).

欣赏一下 cocos2d-objc 的 logo, 如图:
1

如果你对 OC 版感兴趣, 可以通过博文 coco2d-iphone: 环境搭建 去了解.

cocos2d-x 目前支持 JavaScript, lua, c++ 等主流语言来开发.
cocos 还在迅猛发展中, 不断的完善开发工具, 广大游戏开发者依然热力贡献, 程序猿们在游戏的战场挥洒青春.

现在 cocos 的开发者会得到更多的支持.

下面给张图来展示 cocos 家族及其发展:
1

由 libgdx 转向 Cocos2d

几年前, 那个时候还在开发棋牌游戏, 当时自己也是刚刚接触游戏开发这个「高逼格」的行业, 之前自己是个纯 App 开发者.

内心还是蛮激动的, 心想可能要走上人生巅峰了…

棋牌游戏, 当时使用的是 java 的游戏引擎 libgdx 0.X.X 的版本, 该引擎和 Android 基本也是无缝连接, Api 设计的很好.

现在 libgdx 也发展到了1.6.x 版本了, 工具也完善了很多.

虽然 libgdx 也可以跨平台, 但是最终我们还是选择了 cocos2d-x 来移植该游戏.其中原因是因为 cocos2d-x 太火了, 人也好找.

改为 cocos2d-x 的版本之后, 我就被安排到了另外一个项目, 也是一个棋牌游戏, 该游戏现在在腾讯的微信游戏里面运营.

这个游戏是 cocos2d-objc 的引擎写的, 自己也不会 objc, 于是硬着头皮学习, 很快的就上手了这个项目.写的也是风生水起.

cocos2d-objc, 现在也支持跨平台, 并且有 xcode 的插件, 可以在 xcode 里面写 Android 的代码, 调试开发等.

因为接触 cocos2d, 后面就直接开搞 iOS 开发了.

再次使用 Cocos2d

互联网 IT 业的发展, 刺激了各个行业的发展, 也促进和激发了新生的技术, 在这个行业, 每个人都能体会 活到老学到老 这句话的含义.

这两年, HTML5 的发展, 让很多程序员重新认识了 JavaScript 的重要性. 特别是最近 ReactNative 的发展, jsPacth 的开源, 微信小程序的推出, 让 JavaScript 火得不要不要的.

说实话, 是时候开始学习前端相关的技术了, 至少你需要去了解.

cocos2d-js 的发展, 给 HTML 游戏开发带来了很多便利. 最近我们需要开发 H5 的游戏, 直接拿起 coco2d-x(支持 JavaScript) 就撸起.

去 GitHub 上面直接 clone 最新版就可以, 按照 README.md 来搭建环境就好了.

后记

这篇博客也是有感而发, 没有实质性的内容.

主要目的是想告诉大家, 技术的发展日新月异, 想在这里大展拳脚, 你需要保持一颗年轻的心, 不怕苦, 勇往直前的精神.

我们需要学习的技术有很多, 我认为, 要根据项目本身的发展来适度的学习, 切记盲目的学习, 学习一门新技术之后, 要及时的运用在项目当中, 并分享给你身边的人.

不拒绝不排斥新技术, 坚持学习和乐于分享, 应该是必备的技能.

<1…17181920>

193 日志
16 分类
163 标签
© 2024 veryitman