Recent Posts

Subscribe to Recent Posts 130 posts found

posted 8 months ago
liuchunguang 3 posts

Forum: 作品展示 – Topic: 掌上田心

株洲田心社区APP,Appcelerator Studio开发,IOS和安卓客户端 下载地址: https://www.csjixin.com/app/tianxin.html

 
posted 8 months ago
liuchunguang 3 posts

Forum: 作品展示 – Topic: 廉政湘西

湘西州纪委APP,用Appcelerator Studio开发,IOS和安卓同一工程,下载地址也是统一的,欢迎大家下载 下载地址: https://www.csjixin.com/app/xxzjw.html

 
posted 8 months ago
liuchunguang 3 posts

edited 8 months ago

Forum: 开发知识 – Topic: Titanium SDK 5.5.1GA打包IOS企业版错误处理

错误描述:

环境:

Ti SDK:5.5.1GA

Xcode:8.1

日志:

[ERROR] : Error details: Provisioning profile “cdydwqzsproductprofile” doesn’t include the beta-reports-active entitlement.

[ERROR] : Error details: Code signing is required for product type ‘Application’ in SDK ‘iOS 10.1’

处理方法:

工程目录下新建Entitlements.plist文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>beta-reports-active</key>
<false/>
<key>get-task-allow</key>
<false/>
</dict>
</plist>  

原因:企业版证书不包含 beta-reports-active ,而appc运行_build.js打包的时候会读取工程目录下Entitlements.plist文件,如果没有此文件,appc默认将beta-reports-active设置为true,这样将和证书不匹配从而产生错误。

此方法适用于5.5.1.GA及以上

 
posted 11 months ago
wind 2 posts

Forum: 开发知识 – Topic: 修改 app 的图标

而且我的报错提示是文件名不可用,文件名只能是[a-z0-9_.] 当然这个文件名我也试过,也是不行,一模一样的报错。-_-

 
posted 11 months ago
wind 2 posts

Forum: 开发知识 – Topic: 修改 app 的图标

我试了之后失败了?Android下的。-_-111

 
posted 12 months ago
思维 75 posts

Forum: 开发知识 – Topic: 欢迎参与 titanium 中文文档

千万不要使用 Appcelerator Studio. 它要不断的连接国外,根本就没法干活儿。

还是继续使用 command line 吧。 使用 ti sdk . 见我的文档中的内容。

 
posted about 1 year ago
wentaosun 2 posts

Forum: 开发知识 – Topic: 欢迎参与 titanium 中文文档

网上找了一圈,发觉作者的文档是国内少有的中文ti技术文档。 除了appcelerator studio之外,有没有其他好一点的可以调试的ide? appcelerator studio最新版要收费而且用起来太慢了

 
posted about 1 year ago
wentaosun 2 posts

Forum: 开发知识 – Topic: 欢迎参与 titanium 中文文档

github上的链接坏掉了吗?

 
posted about 1 year ago
思维 75 posts

Forum: 开发知识 – Topic: Android下的图片gallery,可缩放

Bitmap too large to be uploaded into a texture (4160x2336, max=4096x4096)

是不是咱们上传的图片不超过 4096 x 4096 就可以了?

 
posted about 1 year ago
张明常 4 posts

Forum: 开发知识 – Topic: Android下的图片gallery,可缩放

这个确实有问题,图片少了还好,多了就报内存错误了。不建议使用

 
posted over 1 year ago
思维 75 posts

Forum: 开发知识 – Topic: Titanium-ListView数据绑定、下拉刷新等常用功能的实现

帅呆了。

 
posted over 1 year ago
theseus 12 posts

Forum: 开发知识 – Topic: Titanium-ListView数据绑定、下拉刷新等常用功能的实现

新增双向数据绑定功能,详见 Titanium-ListView双向数据绑定、下拉刷新等常用功能的实现

 
posted over 1 year ago
思维 75 posts

Forum: 开发知识 – Topic: Titanium-ListView数据绑定、下拉刷新等常用功能的实现

顶! 帮你弄成了可以点击的链接。

 
posted over 1 year ago
theseus 12 posts

edited over 1 year ago

Forum: 开发知识 – Topic: Titanium-ListView数据绑定、下拉刷新等常用功能的实现

https://github.com/jackgreentemp/Titanium-ListView/tree/master/demo_listview

 
posted over 1 year ago
思维 75 posts

Forum: 开发知识 – Topic: 消息推送功能开发案例

非常不错! 赞!

jackgreentemp 是你吗?

 
posted over 1 year ago
theseus 12 posts

Forum: 开发知识 – Topic: 消息推送功能开发案例

https://github.com/jackgreentemp/Titanium-Push-Notification

 
posted over 1 year ago
思维 75 posts

Forum: 开发知识 – Topic: wwdr 过期的问题解决办法

refer to: http://www.appcelerator.com/blog/2016/02/experiencing-ios-certification-issues-check-your-wwdr-intermediate-certificate/

http://stackoverflow.com/questions/35387827/having-an-issue-with-wwdr-appcelerator-titanium-when-building-for-device

正常的 apple WWDR 证书,在2016-2-14过期。 解决办法是:

  1. 删掉原来的 wwdr 证书

  2. 重新下载 这个证书(http://appcelerator.com/ios-wwdr )

  3. 打开钥匙链, 保证这个证书是位于系统(system) 下的。(如果它不在,就用鼠标给它拖过去)

wwdr

 
posted over 1 year ago
思维 75 posts

Forum: 开发知识 – Topic: 修改 app 的图标

对于ios 来说, 要修改 DefaultIcon.png 这个文件.

这个文件名不需要在 tiapp.xml 中定义, ios会默认找到他.

对于android来说, 需要定义在 tiapp.xml 中, 使用 icon 这个节点, 名字必须是小写 a-z0-9

 
posted over 1 year ago
思维 75 posts

Forum: 开发知识 – Topic: titanium app 的 tiapp.xml 中的坑:

tiapp.xml 中的

<name> 节点只能必须是英文, 必须没有空格.</name>

例如:

<name>MyAppName</name>
 
posted over 1 year ago
思维 75 posts

Forum: 开发知识 – Topic: titanium app 修改名字.

要修改名字,使用 i18n的方式:

要想改名字的话,要使用 i18n 特性:

建立下面的文件结构(i18n与Resources处于同级目录):

▾ i18n/
  ▾ en/ 
      app.xml
  ▾ zh/ 
      app.xml
▸ Resources/

两个app.xml 的文件内容都是一样的(目的是,不管是英文的操作系统,还是中文的,都显示一个标题):

<resources>
  <string name="appname">Ti中国社区</string>
</resources>
 
posted over 1 year ago
一叶怀沙 11 posts

Forum: 开发知识 – Topic: 安卓不支持contentOffset.y,有什么替代方法

嗯,是table view的下拉刷新的。谢谢,我先看看尝试一下

 
posted over 1 year ago
思维 75 posts

Forum: 开发知识 – Topic: 安卓不支持contentOffset.y,有什么替代方法

非alloy情况下,我们的安卓有专门的module : com.rkam.swiperefreshlayout

 
posted over 1 year ago
思维 75 posts

Forum: 开发知识 – Topic: 安卓不支持contentOffset.y,有什么替代方法

你这个功能是用在 table view的下拉刷新上吗?

如果是的话,直接使用 android的下拉刷新组件.

或者参考: https://archive.appcelerator.com/question/176986/android-tableview-scroll-event-contentoffset-returning-null (它是使用 可以看到多少个item来判断是否需要刷新啥的)

如果你用的是alloy, 就用这个module: https://github.com/FokkeZB/nl.fokkezb.pullToRefresh

 
posted over 1 year ago
一叶怀沙 11 posts

Forum: 开发知识 – Topic: 安卓不支持contentOffset.y,有什么替代方法

以下是部分代码:

		var _lastY = 0;
		var _max_lastY = 0;
		var _columnH = Math.round(Alloy.Globals.CONST.APP_WIDTH * 4 / 6) + 41;//$.column0.height;
		var _pull_down = 50 - Alloy.Globals.CONST.APP_HEIGHT;//下拉的位置
		
		if (Ienjoy.isIPhone()) {
			_lastY = e.contentOffset.y;
			_lastY < 0 ? _lastY = -_lastY : "";
			if (_lastY > _max_lastY && _lastY > 1000){
				var _this_mark2 = parseInt((_lastY-_pull_down) / _columnH) % 10;
				if (_this_mark2 == 0) {
					if (_this_mark1 == _this_mark2) {
						_p.onClickedTailRow(e);
						_this_mark1 = 1;
					}
				} else {
					_this_mark1 = 0;
				}
				_max_lastY = _lastY;
			}
		}
 
posted over 1 year ago
思维 75 posts

Forum: 开发知识 – Topic: 安卓不支持contentOffset.y,有什么替代方法

你好,能否给出完整一些的代码?

 
posted over 1 year ago
一叶怀沙 11 posts

Forum: 开发知识 – Topic: 安卓不支持contentOffset.y,有什么替代方法

以下是在安卓虚拟机里运行的错误信息。 Runtime Error Message: Uncaught TypeError: Cannot read property ‘y’ of undefined。

官方文档是说这个方法目前只支持ios, http://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.TableView 请问各位是否遇到过?有没有安卓版的替代解决方法。不胜感激。

 
posted over 1 year ago
思维 75 posts

Forum: 其他话题 – Topic: Ti中国社区 手机app端,欢迎大家参与!

hi 大家, Ti 中国社区的 手机app 欢迎大家的参与!

目前的功能有:

  • 查看版面列表
  • 查看话题列表
  • 查看话题内容

还需要有:

  • 登陆
  • 更换头像
  • 发言
 
posted over 1 year ago
思维 75 posts

edited over 1 year ago

Forum: 开发知识 – Topic: 常见的文件下载列表

代理服务器 ssledge http://files.tidev.in//image/6/dist.crx

ANT 1.9.6: http://files.tidev.in//image/8/apache-ant-1.9.6-bin.zip

 
posted over 1 year ago
思维 75 posts

Forum: 其他话题 – Topic: 明星框架 已经开源了

欢迎大家多发 pull request:

https://github.com/star-framework/star-framework

 
posted over 1 year ago
思维 75 posts

Forum: 开发知识 – Topic: 使用明星框架进行敏捷开发

https://github.com/star-framework/star-framework

明星框架

移动开发之殇中我详 细的描述了当前移动开发的痛点:

  • 不敏捷
  • 更新迭代慢
  • 开发效率低

明星框架很好的解决了这些问题。这个框架由 刘明星 建立的,并且在2015年8月的一次 北京 Titanium 社区技术分享上公开给大家。 所以我叫它明星框架。

明星框架的核心理论是:把传统写在客户端的代码写在服务器上。在使用Titanium之前, 明星也在其他语言上有过类似的成功经验。

明星框架完全解决了移动开发不敏捷的问题。可以极大的提高开发效率。它的地址是:

https://github.com/star-framework/star-framework

把原本写在app上的代码,放到服务器端

把app的代码写到服务器端,然后在app端访问远程界面。 把代码缓存到本地。 使用 eval () 来调用。

这个框架能够实现,在技术上有几种依托:

  1. 代码不需要编译。

  2. 支持eval 这样的方法

好处是:

  1. 不需要编译的等待时间。 这边写了那边立马看到

  2. 可以随时随地修改app上的代码。

前景:

这个框架绝对是一种变革.

我们把Titanium 看成是 nginx, 则android 就是linux. 我们在linux上写html是不需要编译的, 同理,我写mobile app, 骨架部分需要编译, 肌肉部分是不需要的。

过程:

假设你的代码,在titanium上是静态代码:

app.js:

window = Ti.UI.createWindow({
    title: '本地的工地'
})
label = Ti.UI.createLabel({
    text: '这里的内容是本地的,将来要放到远程上'
})
window.add(label)
window.open()

那么,我们要做的是:

  1. 先把这个window 在app.js中 抽取出来,成为一个 js module:

app目录下的 /Resources/lib/foo.js:

Foo = function(){
    window = Ti.UI.createWindow({
        title: '某个窗口'
    })
    label = Ti.UI.createLabel({
        text: '这里的内容是本地的,将来要放到远程上'
    })
    window.add(label)
    return window;
}

module.exports = Foo;
  1. Resources/app.js 中,使用 require 来调用这个module:
wrapper = require('lib/foo.js');
wrapper.open();

运行,没问题~

  1. 开始分解 foo.js, 把它的内容改成如下:
function FooWindow(title) {
	var win = Ti.UI.createWindow({
		title: "某个窗体,现在要放到远程了。"
	});

	function make_foo_win(){
		http_call({url: "http://myserver.com/code/foo.js",
      cache: true,
      success: function(e){
        // 这里是关键:
        var MakeUserWin = eval(e.responseText);
        MakeUserWin(win);
      }
    });
	}

	make_foo_win();
	return win;
};

module.exports = FooWindow;

这个 http_call 的方法看起来这样:( 放到 Resources/lib/public.js 中)

function http_call(options){
  // 如果
	if (options.cache){
		if (Ti.App.deployType == "production"){
			var record = require('/lib/db').db.select_with_check(options.url, 0);
      //没有命中
			if (record.blank){
				//啥也不干,等着后面处理
			}
      //命中了
			else{
				if (options.success)
					options.success({responseText: record.json});
				return;
			}
		}
	}
	var xhr = Ti.Network.createHTTPClient();
	xhr.timeout = Ti.App.timeout;
	xhr.cache = false;
	xhr.onerror = function() {
		if (options.error)
			options.error(this);
		else
			show_timeout_dlg(xhr, options.url);
	};
	xhr.onload = function() {
		if (options.success)
			options.success(this);

		if (options.cache)
			require('/lib/db').db.insert_json(options.url, 0, this.responseText);
	};
	var url = options.url;

	xhr.open(options.method || 'GET', url);
	if (options.args){
		xhr.send(options.args);
	}
	else{
		xhr.send();
	}
}

对于 lib/db.js 就是操作数据库的 :

var StarFramework;
StarFramework = StarFramework || {};
StarFramework.db = {};
StarFramework.db.insert_json = function(json_type, id, json) {
  var mili_seconds, now;
  now = new Date;
  mili_seconds = now.getTime();
  Ti.App.db.execute('delete from jsons where json_type = ? and id = ?', json_type, id + '');
  Ti.App.db.execute('INSERT INTO jsons (json_type, id, json, created_at) VALUES (?,?,?,?)', json_type, id + '', json, mili_seconds);
  Ti.API.log('insert json ' + json_type + ' ' + id);
};

StarFramework.db.insert_json_if_not_exist = function(json_type, id, json) {
  var mili_seconds, now, record;
  now = new Date;
  record = Ti.App.db.execute('SELECT * FROM jsons where json_type=? and id=?', json_type, id + '');
  if (!record.isValidRow()) {
    mili_seconds = now.getTime();
    Ti.App.db.execute('INSERT INTO jsons (json_type, id, json, created_at) VALUES (?,?,?,?)', json_type, id + '', json, mili_seconds);
    Ti.API.log('insert json ' + json_type + ' ' + id);
  }
};

StarFramework.db.select_one_json = function(json_type, id) {
  var record, result;
  record = Ti.App.db.execute('SELECT * FROM jsons where json_type=? and id=?', json_type, id + '');
  Ti.API.log('select json ' + json_type + ' ' + id);
  result = null;
  if (record.isValidRow()) {
    result = {
      json: record.fieldByName('json'),
      created_at: record.fieldByName('created_at'),
      blank: false
    };
  } else {
    result = {
      blank: true
    };
  }
  record.close();
  return result;
};

StarFramework.db.select_with_check = function(json_type, id) {
  var now, record;
  record = StarFramework.db.select_one_json(json_type, id);
  now = new Date;
  if (Titanium.Network.online && !record.blank && now.getTime() - record.created_at > 1000 * 3600 * 24 * 3) {
    StarFramework.db.delete_one_json(json_type, id);
    return {
      blank: true
    };
  }
  return record;
};

StarFramework.db.delete_one_json = function(json_type, id) {
  Ti.App.db.execute('delete from jsons where json_type=? and id=?', json_type, id);
};

module.exports = StarFramework;

同时,你要有个远程服务器,在远程服务器的 /code/foo.js 中,要返回这个内容:

FooWindow = function(window) {
  Ti.include('/lib/public.js');
  label = Ti.UI.createLabel({
    text: '这个Label被放到了远程服务器上'
  })
  window.add(label);
  return window;
};

module.exports = FooWindow;

现在,你要修改window的代码的话,完全不需要编译重启app, 直接在远程修改就完事儿了。

注意:native module要提前放到app上。

一些module , 不但文件需要放到本地, 代码运行最好也在本地, 否则会出现 有时加载不了的情况。 深层原因疑似 网络加载有延迟。 放到本地的话就没有了。

注意:一些方法,要提前让app加载并运行。

这个文件,系统是不会调用的。 它存在的目的,是为了骗过编译器,(先调用一些API, createTextArea, createOptionDialog) 让编译到实体机时,系统不会出错。 要有这个文件,Resources/function_place_holder.js:

function FunctionPlaceHolderWindow(title) {
  var t = Ti.UI.createTextArea({
    hintText: "反馈内容"
  });

  var optionsDialogOpts = {
    title: "选择您想进行的操作",
    options : ["1", "2"],
    cancel : 1
  };

  Titanium.UI.createOptionDialog(optionsDialogOpts);

  Ti.Filesystem.applicationCacheDirectory;

  Titanium.UI.iPhone.TableViewStyle.GROUPED,
  Ti.Geolocation.preferredProvider = "gps";
}

module.exports = FunctionPlaceHolderWindow;

在服务器端做控制,随时升级

想要升级,可以自动做,也可以手动做这个事儿。

原理:清除本地数据库的代码即可。

这样的话,用户再次打开app时,app 发现本地没有代码,就会向远程发起请求, 获取新的代码,并把新代码保存到本地数据库中。

clean_cache = function() {
  Ti.App.db.execute("delete from jsons where json_type <> 'foo'");
};

自动做升级

在app 启动后,肯定要访问远程的接口,我们管这个接口叫 “初始化接口”,它会为 app提供各种初始化的参数。例如:

http://yourserver.com/interface/init.json:

{
  app_version: '1.0.3'
}

当客户端获知该接口后,就会把这个 app_version 与本机保存的版本做比较,再决定 是否升级。

手动做升级

直接告诉你的用户,进入到“清空缓存”的页面,点击清空缓存,即可。

自动适配多种不同机型和屏幕

靠下面这段代码实现:

function __l(x){
  if (Ti.App.is_android){
    if (Ti.App.platform_height/Ti.App.logicalDensityFactor > 800)
      return x * Ti.App.logicalDensityFactor * 1.4;
    else
      return x * Ti.App.logicalDensityFactor;
  }
  if (!Ti.App.is_android && !Ti.App.is_ipad && Ti.App.platform_width > 320){
    return parseInt(375.0*x/320);
  }
  return Ti.App.is_ipad ? 1.5*x : x;
}

这个代码的作用不是简单的按百分比缩放,而是在某范围内的屏幕下有个特定的尺寸, 在另一个范围内的屏幕尺寸下,再有个特定的尺寸。

使用方式:

Ti.UI.createLabel({
  width: __l(50);
});

善用TableView

虽然ListView是Titanium 目前提倡的UI组件,执行效率比较高,但是也有很明显的缺点:

难以动态的修改样式

而TableView就没有这个问题。而且随着现在移动设备的性能越来越高,TableView也 用起来很好用。

在我看来,只有当某个列表超过了512行时,把TableView 换成 ListView.