ios项目,都会有一个名为project.pbxproj的文件,这里面保存了项目的基本配置,例如你的项目有几个target,用什么证书之类。
笔者之前因项目需要,需要从这个文件中读取target、configuration等信息,本来想自己写程序实现。后来发现在github上面,已经有人实现了。用起来比较方便,不敢独享,在此分享。
一、用途(示例代码)
/* * #%L * xcode-project-reader * %% * Copyright (C) 2012 SAP AG * %% * Licensed 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. * #L% */ package com.sap.prd.mobile.ios.mios.xcodeprojreader; import static org.junit.Assert.assertEquals; import org.junit.Test; import com.sap.prd.mobile.ios.mios.xcodeprojreader.buildphases.BuildPhase; import com.sap.prd.mobile.ios.mios.xcodeprojreader.buildphases.PBXShellScriptBuildPhase; import com.sap.prd.mobile.ios.mios.xcodeprojreader.jaxb.JAXBPlistParser; import com.sap.prd.mobile.ios.mios.xcodeprojreader.jaxb.JAXBPlistParserTest; public class UsageExamples { @Test public void usage() throws Exception { JAXBPlistParser parser = new JAXBPlistParser(); // Optional step, if project file is not already in XML format. // parser.convert(JAXBPlistParserTest.fileName, JAXBPlistParserTest.fileName) Plist plist = parser.load(JAXBPlistParserTest.fileName); ProjectFile projectFile = new ProjectFile(plist); assertEquals("46", projectFile.getObjectVersion()); Project project = projectFile.getProject(); Target target = project.getTargets().get(0); assertEquals("MyTest", target.getName()); target = project.getTargets().getByName("MyTest"); assertEquals("MyTest", target.getName()); BuildConfiguration config = project.getBuildConfigurationList().getBuildConfigurations().get(0); assertEquals("Debug", config.getName()); config = project.getBuildConfigurationList().getBuildConfigurations().getByName("Release"); assertEquals("Release", config.getName()); BuildSettings buildSettings = config.getBuildSettings(); assertEquals("5.1", buildSettings.getDict().getString("IPHONEOS_DEPLOYMENT_TARGET")); assertEquals("YES", buildSettings.getDict().getString("VALIDATE_PRODUCT")); // LOW LEVEL (not recommended) Array buildPhaseRefs = project.getTargets().get(0).getDict().getArray("buildPhases"); String ref = projectFile.generateReference(); buildPhaseRefs.add(ref); Dict phase = projectFile.createDict(); phase.put("isa", "PBXShellScriptBuildPhase"); phase.put("files", projectFile.createArray()); phase.put("inputPaths", projectFile.createArray()); phase.put("outputPaths", projectFile.createArray()); phase.put("runOnlyForDeploymentPostprocessing", "0"); phase.put("shellPath", "/bin/sh"); phase.put("shellScript", "env > test.txt"); projectFile.setObjectByReference(ref, phase); // HIGH LEVEL ReferenceArray<BuildPhase> buildPhases = project.getTargets().get(0).getBuildPhases(); PBXShellScriptBuildPhase phase2 = new PBXShellScriptBuildPhase(projectFile); phase2.setDefaultValues(); phase2.setShellScript("env > test.txt"); buildPhases.add(phase2); /* * Note: Collections are created on the fly. * * project.getTargets().get(0).getBuildPhases().size() would create a collection of targets and * a collection of build phases if they don't exist. This is important to know, if you intend to * save the property list later. If you don't want this behavior, you have to use the low level * APIs. */ // Save back to disk // parser.save(plist, JAXBPlistParserTest.fileName); } }
二、如何获取
项目的github网址:https://github.com/sap-production/XcodeProjectJavaAPI
公司购买了企业邮局给员工提供邮件服务,这样收发外部邮件都没有问题,但有个非常不好的地方,绝大多数邮件都是在内部互相之间转发的 ,结果就导致一个问题,不管这个邮件是不是发给内部的, 邮件都得到外部邮件服务器上转一圈,如果邮件小还好说,有时候数MB的附件,一发一收都得占不少网络资源,一直就想找个办法,能否让发往内部的邮件不需要外部邮件服务器中转,直接局域网内部就搞定了,外部邮件通过外部服务器收发呢?当然,基本上大部分邮件服务器都有这样的功能,但都或者庞大无比,或者价值不菲,当然,linux下有许多开源软件可以搞定,但公司还有许多软件需要运行在windows下,而且linux下的邮件服务器配置复杂啊。
偶然之间发现了hMailServer这个好email server,hMailServer是仅运行在windows下的一个邮件服务器,首先,hMailServer体积很小,最新版的5.3.2也仅仅3M多,别看hMail体积小,但它提供的功能可不少,POP3、SMTP、IMAP服务、多域名、别名、SSL支持、防病毒、防垃圾、内置备份功能、脚本支持、服务端规则支持、多语言、MYSQL、PostgreSQL或MSSQL后端支持、web管理界面等等,别的邮件服务器有的功能基本上hMail都具备了,最最重要的,hMailServer是开源软件,完全免费使用,hmaiserver配置也非常简单,下面就开始吧 。
hMailServer需要.Net Framework 2.0的支持,所以先安装好.NetFramework 2.0,也可以先不安装,那么会在hMailServer安装途中提示在线安装.net Framework 2.0,下面看我们今天需要的软件。
1、hMailServer 5.3.2,可以在hMail官方网站下载。
2、hMailServer 5.3汉化包,可以在网上搜到,其实很简单,也就是一个.ini文件
3、WampServer 2.0,这是一个windows下的apache+mysql+php的服务器软件,免费简单实用,可在wampserver官方网站下载
,如果仅仅需要实现hMailServer的功能可以不需要wampserver,只是这里我添加了webmail的支持,所以需要php的支持。
4、webmail,hmailserver本身没有提供webmail,AfterLogic Webmail Lite PHP,是一个非常易用的webmail,支持AJAX和皮肤更换。支持POP3、IMAP和 SMTP,安装非常简单,需要PHP和MYSQL的支持,另外还有个.Net版的,这里我就实用PHP版的了,可在AfterLogic官网上下载。你也可以选择其他的webmail如squirrelmail、roundcube
webmail,这个凭个人喜好。
下面开始安装
WampServer的安装就不多说了,很简单
hmaiserver的安装也很简单,把hMailServer安装到独立的分区
用户不多,我就直接使用内置的数据库引擎mssql ce,如果用户多的话,可以选择下面的mysql、mssql、postgresql数据库
事先没有安装.NetFramework 2.0的提示
设置hMailServer管理密码
安装完成后,把汉化文件里的chinese.ini复制到hMailServer安装目录的languages目录下,因为这个汉化文件是5.3的,对比英文语言文件,把缺少的两行复制过来,随便翻译一下
然后打开到bin目录下的hMailServer.ini文件,在GUILanguages字段下增加chinese的支持
把hMailServer的服务停止再启动一下
打开hMailServer Administrator,连接本地服务器,密码就是安装hMailServer时设置的管理密码了
进入到管理界面,选择菜单"File"里的"Select Language",选"chinese",重新连接,界面就变成中文了
OK,先添加一个域,这里就是viside.com,这个viside.com我申请了google的企业邮局,这样我可以内部跟外部通用一个账号,保存先
更改一下限制,域使用的空间、邮件的最大尺寸、用户最大空间、用户数等等,这里整个邮局给50G,每个用户1G,允许最大的邮件为50M,太大了对服务器的压力太大了。
增加了域再增加账号,输入用户名、密码,保存,嗯?出错了,大概意思就是说域有限制每个用户的空间,这里也要设置一下用户空间大小,嗯,不超过1G就可以保存了。
其实到这里就可以使用了,但开始说过是要实现内部邮件直接局域网内转发,外部邮件由外部的邮件服务器收发,接下来设置外部邮件的收取,点上面的外部账号,设置一下,这里只能使用POP3收取,GMAIL的POP3比较特殊,首先得在GMAIL里设置启用POP3,而且必须使用SSL,端口为995,间隔时间改短点,我这里只是为了试验,改为了0,这样不太好,5分钟差不多够了,设置完了点一下下载
发送的也设置一下,这样统一用admin@viside.com这个账号发出,如果是其他账号呢?人家回复会回复到哪里?没问题的。GMAIL的SMTP跟POP3一样都要使用SSL,端口为465
现在通过foxmail来测试一下
这里账号名也要填全,如果在“设置”,“高级”中的默认域名有设置过默认域名为viside.com的话,这里可以只填用户名不用填后面的域名,如果你要使用多个域,除了默认域名的邮箱,其他域的邮箱就要填全称了
我这在本地测试,接收和发送服务器都填localhost,如果在局域网内其他客户端测试就要填hMailServer服务器的IP
测试一下,通过了
收一下邮件,已经收到部分了
现在测试往外发送,先看看126邮箱里现有的邮件
发一个给126邮箱
可以看到马上126邮箱就收到了邮件
看看内容
下面来设置hMailServer服务器的web管理和webmail,web管理是软件里自带的PHPWebAdmin,webmail就直接把AfterLogic Webmail Lite解压出来
先配置PHPWebAdmin,将目录下的config-dist.php改名为config.php
编辑config.php,设置$hmail_config['rooturl']和$hmail_config['defaultlanguage'],这里设为IP地址,免得从局域网其它地方导致无法访问的问题,至于如果要能外部访问,那得使用域名,语言改为中文,这样默认登录就是中文了
与以往一样,仍然是零分下载。
本次lisk中添加了tcp客户端接口,其实只添加了一个对外接口以保持网络框架接口的简洁性。单进程下的lisk算是完美了。以后工作中如果用到多线程,并且本人多线程使用经验丰富之后,再考虑lisk多线程版本的开发,省得误人子弟。
五一之前曾考虑开发windows版本,现在恐怕要跳票了。因为如果要开发win版,第一网络部分我就得学习windows的iocp,而目前暂无兴趣学习使用它,第二其他的内存操作部分并无linux与windows的区别,而且vs2012现在我看也可以完美支持gcc的部分特性,基于上面两条原因我就不开发win版本的lisk了。
使用lisk下的网络测试用例network_client_test与network_server_test的时候,请注意修改lisk/exam/lisk.conf文件中的IP地址。
另外,运行那两个测试用例的时候,程序可能有以下错误提示:
2013-05-03_01-57-19_1367560639, lisk/src/lisk_network.c-set_max_sock_num-1165, [ERROR]: setrlimit(RLIMIT_NOFILE, &limit = 0x7fffbf23ac80) = -1, Err code 1, Operation not permitted
2013-05-03_01-57-19_1367560639, lisk/src/lisk_network.c-set_max_sock_num-1166, [ERROR]: ret = -1, setrlimit(RLIMIT_NOFILE) = -1
这是由于文件lisk/src/lisk_network.c使用了setrlimit函数,用户身份须为root。
所以这个问题有两个解决办法:第一,用sudo获取root权限,然后运行测试用例;第二,让他继续跑下去好了,如果仅仅是为了测试框架的可用性,这个错误不会影响测试结果的正确性。