iOS

Cocos2d-JS HTML5的cc.audioEngine音乐音效在iOS设备上不响应静音键的问题

之前写过一篇同样关于Cocos2d-JS H5的音频播放相关的文章: DOMException: play() can only be initiated by a user gesture(Cocos2d-JS HTML5),其中提到了移动端上H5的声音播放需要在用户操作后且必须在操作后一定时间内的问题,这次记录的问题也与此问题有关,直接现象为Cocos2d-JS(我用的3.13 lite版,通过js-builder获取:http://www.cocos2d-x.org/filecenter/jsbuilder,本文所描述问题可能仅与此版本相关!)的H5游戏在iOS设备上播放的音乐音效不受静音键影响,无法根据静音键静音!
做过iOS音频相关原生开发的应该知道,iOS通过对AVAudioSession的Category设置来决定应用的音频播放所属的分类,从而决定是否受静音键的影响,比如,静音开关开启的时候,短信音,Push消息提示音之类的会不播放,但优酷视频,虾米音乐之类的应用的音频还是会播放,不受影响,具体参考如下:

会话类型 说明 是否要求输入 是否要求输出 是否遵从静音键
AVAudioSessionCategoryAmbient 混音播放,可以与其他音频应用同时播放
AVAudioSessionCategorySoloAmbient 独占播放
AVAudioSessionCategoryPlayback 后台播放,独占
AVAudioSessionCategoryRecord 录音模式
AVAudioSessionCategoryPlayAndRecord 播放和录音,此时可以录音也可以播放
AVAudioSessionCategoryAudioProcessing 硬件解码音频,此时不能播放和录制
AVAudioSessionCategoryMultiRoute 多种输入输出,例如可以耳机、USB设备同时播放

 

Continue reading…

对Unity3D的iOS导出插件XUPorter的plist处理功能的改进

XUPorter

是一个可以在U3D生成iOS所需Xcode项目时自动完成一些如添加framework,修改编译参数等操作的Editor插件。这个插件对于同一个项目需要接入各种不同渠道的SDK生成对应IPA的需求可以很方便快捷的实现自动化操作,降低项目维护复杂度。
在使用这个插件时,发现了些小问题,查看作者声明时发现其已经不在对这个插件进行维护了,于是只好自己动手做一些修改完善:
本文记录的就是对plist的处理功能,原代码逻辑中XCProject.cs中的ApplyMod函数会根据.projmods的信息对Xcode项目文件进行一系列的修改,其中一部是对项目.plist的修改,但这一步用我当时取到的github最新版本时会出错,仔细检查了下,发现无论projmods中的plist段写不写,生成对应的XCMod对象的plist总会是null,检查了下这个json数据解析生成类,发现plist的类型是“Hashtable”,而不像其他一些字段,如group是string,libs是ArrayList等,改换了下projmods中的json写法,又发现虽然可以解析成功不为null了,但实际修改plist逻辑又出现了问题,原逻辑是通过XCPlist的Process函数对projmods中提供的信息项对原项目plist进行合并修改,但是代码中对各种plist选项的处理不并完善,只有一个特殊if:

		public void AddPlistItems(string key, object value, Dictionary<string, object> dict)
		{
			Debug.Log ("AddPlistItems: key=" + key);
			
			if (key.CompareTo(PlistUrlType) == 0)
			{
				processUrlTypes((ArrayList)value, dict);
			}
			else
			{
				dict[key] = HashtableToDictionary<string, object>((Hashtable)value);
				plistModified = true;
			}
		}

会对URLSchemes做处理,显然这样无法实现通用的plist修改逻辑,思考过后我决定将其实现改为读取指定plist文件中的key项并与项目plist进行合并,覆盖已有的项,添加没有的项,具体实现如下:
Continue reading…

iOS Android平台下的wchar_t默认size问题

很久以前曾经被wchar的问题在iOS和Android上被坑过,这次是在参研一份有年头的代码时又遇到了宽字符的问题,当然,也是和wchar有关系的,就是这个wchar在各个系统平台下的sizeof问题,关键的是一段UTF-8转UTF-16的代码:

size_t Utf8ToUtf16(const char* src_, wchar_t* dest_, size_t destlen_, size_t srclen_ /*= 0*/) 
{
	if (srclen_ == 0)
		srclen_ = _utf_length(src_);
	size_t destcapacity = destlen_;
	for (size_t idx = 0; ((idx < srclen_) && (destcapacity > 0));)
	{
		wchar_t	cp;
		unsigned char	cu = src_[idx++];
		if (cu < 0x80)
			cp = (wchar_t)(cu);
		else if (cu < 0xE0)
		{
			cp = ((cu & 0x1F) << 6);
			cp |= (src_[idx++] & 0x3F);
		}
		else if (cu < 0xF0)
		{
			cp = ((cu & 0x0F) << 12);
			cp |= ((src_[idx++] & 0x3F) << 6);
			cp |= (src_[idx++] & 0x3F);
		}
		else
		{
			cp = L'?';
		}
		*dest_++ = cp;
		--destcapacity;
	}
	return destlen_ - destcapacity;
}

这段代码在win下可以正常将utf-8的char*转换为utf-16的char*,但在Android, iOS下却不能得到和win下一样的转换结果,刚发现这个问题时,以为又是当年遇到的wchar坑,宽字符函数不支持之类的,但是仔细看了下并没有用到什么字符串函数,转换部分也是自己实现的,最后在各平台调试器的帮助下找到了问题:
Continue reading…

使用图片方式自定义iOS导航栏navigationItem的backBarButtonItem

在做ViewControlller的navigationItem时,我们经常需要使用自定义的图片来替换系统默认的按钮样式,这点在对普通导航项,比如leftBarButtonItem或rightBarButtonItem来说还是比较简单的,通过UIBarButtonItem的setImage设置做好的图片按钮,然后再通过

[item setBackgroundImage:[UIImage new] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

去掉默认的背景image就可以了。但是如果是想自定义特殊的backBarButtonItem就比较麻烦了, Continue reading…

iOS程序开发引用的第三方库之间出现duplicate symbol时的处理方法

iOS程序集成的第三方库过多时,很容易出现某几个库同时用到了一样的函数库,也就是在你的程序link时会提示duplicate symbol,而重复的符号又不是由你自己程序的代码造成的,也就说没法通过直接修改代码把重复的符号去掉!这样呢,要不就要求第三方库提供方该代码,要不就自己修改第三方库的库文件。第一种方法多少有点无理要求,所以还是直接用第二种方法自己解决了吧,也就是直接修改.a文件或framework里的库二进制文件:

Continue reading…

我遇到的An error occurred uploading to the itunes store问题

最近一次更新App版本到itunes时遇到了An error occurred uploading to the itunes store,用的是XCode自带的Organizer做的归档上传操作,提示这个问题后存档被归为validating失败,感觉很奇怪,于是手动validate了一次,顺利pass,没有任何问题!

然后开始怀疑是网络问题,retry了3、4次,问题依旧,看来不是偶然,于是开始google,发现遇到同样问题的人还真是不少!

问题的根源就是XCode需要的Java环境出现了问题,网上找到的解决方案是这样:

cd /System/Library/Frameworks/JavaVM.framework/Versions
sudo ln -s CurrentJDK /System/Library/Frameworks/JavaVM.framework/Versions/1.5
sudo ln -s CurrentJDK /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0

试了一下,问题依旧!
Continue reading…

UIImagePickerController在iPad上应用与iPhone类设备上的应用区别以及sourceType导致的crash

之前调用UIImagePickerController显示照相机和相册时用的一直是presentModalViewController:方法直接显示,后来发现这样的用法在New iPad上会导致:
Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘On iPad, UIImagePickerController must be presented via UIPopoverController
这个错误,并且这个错误只出现在显示系统相册时,照相模式时不会提示这个错误。

按照错误字面意思来看,在iPad上UIImagePickerController必须通过UIPopoverController来显示,g了一下,发现提到相关问题的文章也有很多,替换的具体实现可以看下面的参考链接。可是奇怪的问题是直接presentModalViewController的方法实际测试在iPad2上面没有任何问题,关于这点我看到有老外提到说这个可能是UIKit的bug?!

另外,我发现在替换了UIPopoverController的实现后,打开相册时在小框里狂托时会有极大的可能性导致crash,有时候时EXC_BAD_ACCESS,有时候Collection mutated while being enumerated,还有时候提示数组0索引位置不可用…
Continue reading…

iOS6对于shouldAutorotateToInterfaceOrientation的改动以及其他一些窗口相关细节

iOS6正式版发布当天博主我就更新了,随后也更新了对应的XCode以及iOS SDK,更新到了4.5 (4G182)。然后更新原有4.4 iOS5 SDK的项目,目前最主要的发现就是iOS6对于app屏幕朝向支持以及自动旋屏时的处理方式的变动。

简而言之就是iOS6下的

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
	return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
}

这个不会再被调用,取而代之的是这俩个组合:

- (BOOL)shouldAutorotate
{
	return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
	return UIInterfaceOrientationMaskLandscape;
}

当然,为了保持对旧版本系统行为的兼容性,不要删掉不用的那个调用。另外还有一个这个preferred朝向也可以加上

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
	return UIInterfaceOrientationLandscapeRight;
}

当我替换完这俩个操作后尝试运行app,发现会报如下的异常:
Terminating app due to uncaught exception ‘UIApplicationInvalidInterfaceOrientation’, reason: ‘Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES’
Continue reading…

iOS的UDID废用以及UUID配合keychain的替换方案实现

首先,简单介绍一下UDID这个东西:

UDIDUnique Device Identifier的简称,也就是唯一设备标识的意思。于iOS SDK中取得的方法是UIDevice的一个叫uniqueIdentifier的NSString*,由于这个ID字符串是基于设备的,应用开发人员可以通过获取此ID来用于记录区分设备。正是由于这个特性,可能会导致一些隐私等等相关的问题,Apple于iOS5中将这个UDID废掉了,SDK中被标记为了Deprecated,虽然为了兼容低版本的源代码而继续存在,但并不会再返回任何有实际意义的东西。

最近在做Flurry的统计功能时,发现还是需要用到可以识别设备的东西的,好方便分析数据,经过一段时间的研究、试验,发现了这个应该还算是比较靠谱的方法……

Continue reading…

[译]如何指定iOS应用程序所支持的设备

免责申明:本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播。同时,转载时不要移除本申明。如产生任何纠纷,均与本博客所有人、发表该翻译稿之人无任何关系。谢谢合作!原文链接:How to Indicate What Devices Are Supported by Your iOS App – http://blog.manbolo.com/2012/05/02/how-to-indicate-what-devices-are-supported-by-your-ios-app,由于本人水平有限,翻译不当之处欢迎留言指出!

Hypercritical n°64 “You Will Die Instantly!”这里,John Siracusa讨论了一个由于应用程序设备兼容性和iTunes信息之间不符导致的iOS问题。这个问题的具体是说有用户抱怨其所下载的游戏不能在iPhone 3G上运行,而iTunes上却声明这个游戏支持包括3G在内的全部设备。用户抱怨的同时,游戏开发人员却争执说应用介绍信息中明确指出了这个游戏不支持iPhone 3G,但是iTunes标签信息中却给出了相反的信息。这么看来,iTunes上的信息和应用描述信息之间似乎却有不一,而系统则应该尽量避免发生此类问题。

Continue reading…