控制iPhone短信收发

盛大最近在做“有你”类似iMesssage、TextFreek、biteSMS的应用,主要功能是拦截短信录取联系人并控制短信收发。Android、Symbian等其他移动平台都可以,唯独iOS这块不行,没有这个官方SDK和权限。需要越狱才能达到以上这些功能。

虽然这个有点不太道德,但是还是答应下来。最近两天潜心研究,得出成果,如下:

发短信一般有两种方式,一是打开/dev/tty.debug使用AT命令操作,二是直接使用apple的私有库(CoreTelephony)操作。

第一种:
使用通过minicom的sendmodem(http://code.google.com/p/iphone-elite/wiki/sendmodem)发送AT。
像设置信息格式等一般的命令都可以很好的执行,但是像读取信息、发送信息等这样的命令一概会报ERROR。
而且这个方法有个弊端,因为minicom一定要再关闭通讯中心(launchctl unload -w /System/Library/LaunchDaemons/com.apple.CommCenter.plist
后才能使用,所以在执行AT命令过程中是没有其他程序能够通过运营商通道通讯,比如不能通过原有程序打电话和发短信。

以下是收集的一些AT资源:
sendmodem:http://code.google.com/p/iphone-elite/wiki/sendmodem
C:http://blog.csdn.net/xinghexiyue/archive/2011/03/23/6270732.aspx
iphone-sms:http://code.google.com/p/iphone-sms/
A Convenient Tool to Send AT Commands:http://george.insideiphone.com/index.php/2007/11/25/a-convenient-tool-to-send-at-commands/

第二种:
添加CoreTelephony框架(在4.0以下是Private API),但是在4.0以上这个框架变成Public API,取消了所有的通讯功能,只有一些无关痛痒的功能(比如返回运营商信息)。

第三种:
使用 MessageUI框架中的MFMessageComposeViewController,可以在App中发送短信。但是不能修改发送短信UI,也不能自动发送短信。

总结:
以上方法对于“有你”的要求都不行。还有几个方法在尝试中,测试完毕也会及时更新。

AppStore SDK

AppStore SDK

AppStore SDK enables you to retrieve information about all apps from App Store. With AppStore SDK you are able to discover 200,000 of apps that let you do even more:

http://www.app-storage.com/

 

PS:这个是第三方的,是从网页上直接抓取的,使用下来效果并不理想,但是有需要只能用了。

Apple Developer 续费问题

今天登录http://developer.apple.com/iphone/index.action,发现:

Your iOS Developer Program is about to expire.

按照提示操作,进入填写Purchase Form,里面的填空有一个是Apple Develop Program Enrollment ID哪儿都找不到,只有找到Company ID。

然后网上查了下,都是这种情况,只能把Company ID填写上去。

其实Enrollment ID申请的时候有的,但是谁还会记得1年前申请的这个ID呢,这个是Apple的一个疏忽。

iOS视频录制

这几天要为AD的iPad版做宣传。之前试过拍摄,但是拍摄的效果(比如阴影和反光)不好。所以最好的方案还是录制视频。

iPad:使用Display Recorder进行录制。

Mac:使用iDown实时传输iPad录制视频到Mac上,并是使用Screenium录制。

PS:iPad上的Display Recorder可以自己保存avi或者是mov。

 

App Store退回

今天上传审批的FSWeather终于得到了feedback,邮件如下:

iTunes Connect

Hello Flipscript Co., Ltd,

Thank you for submitting FSWeather to the App Store.

We've completed the review of your app, but cannot post this version to the App Store because it did not comply with the App Store Review Guidelines, as detailed below:

  • 2.3: Apps that do not perform as advertised by the developer will be rejected

To reply to this message or to get more information, visit the Resolution Center in iTunes Connect. Do not reply directly to this email.

Regards,

App Review

Converse with fellow developers and Apple engineers on technical topics.
Apple Developer Forums ― http://devforums.apple.com

iTunes Connect

意思是说广告性太强。。。因为之前知道一些朋友也遇到过这个问题,所以直接向他们请教。问题应该是提供的描述、截图与上传的App内容不符,所以修改了一下copyright,再次上传审批。

条形码 for iOS

  • Kaywa Reader is one of the most impressive commercial readers. Notably, it can recognize codes in a video stream from the phone's camera. The user never needs to press a button to take a picture.
  • Libdmtx* is an open source (LGPL) library for decoding Datamatrix codes. It is designed to be highly portable, and it is written in C. It was recently made available again after a year-long break.
  • ZXing* is an open source (Apache 2.0) application recently released by Google that aims to "support decoding of QR Codes, Data Matrix, and the UPC family of 1D barcodes."
  • Open Source QR Code Library* - This is an open source decoding library from Japan.

 

iOS录音问题

问题描述
AD的iPad版有一个鼓掌互动的应用。换了前后三套类库,如下:
SCListener:https://gist.github.com/72914
AVAudioRecorder:http://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVAudioRecorder_ClassReference/Reference/Reference.html
SpeakHere:http://developer.apple.com/library/ios/#samplecode/SpeakHere/Introduction/Intro.html

问题分析
首先使用SCListener,发现模拟器上正常使用,但是真机不能监听声音。再使用AVAudioRecorder,发现还是有以上真机不能监听的问题。
最后使用SpeakHere,可以监听,但是有一个bug。就是:真机上,声音监听过就不能播放video,而模拟器上一切正常。

问题解决
原来录音和播放使用的是一个通道,需要手动设置当前通道的状态。而模拟器上就可以忽略这种限制。
修改通道为录音的代码如下:
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryRecord error:nil];

修改通道为播放的代码如下:
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];

播放前修改为播放,录音前修改为录音,一切OK了。

PS:后来发现只要修改对应的通道,AVAudioRecorder在真机上也可以用了。

cocos2d多个CCSprite同时运行带CCCallFuncN的Action后会造成调用丢失

问题描述
昨天晚上通宵改Geely iPad的bug,这个bug改了8个小时。问题是程序会泄露导致崩溃。

问题分析
项目使用的是cocos2d,所以也不能使用Instruments做性能测试。一步一步发现一个CCLayer没有dealloc,于是进去一步一步查,一段段的注释和启用。最后发现有了这段代码就会出现泄露崩溃:

[vBackground stopAllActions];

[vMenu stopAllActions];

id backgroundFaceAction=[CCFadeOut actionWithDuration:0.7];

id backgroundCallAction=[CCCallFuncN actionWithTarget:self selector:@selector(removeNode:)];

id backgroundSequenceAction=[CCSequence actions:backgroundFaceAction, backgroundCallAction, nil];

id menuFaceAction=[CCFadeOut actionWithDuration:0.7];

id menuCallAction=[CCCallFuncN actionWithTarget:self selector:@selector(removeNode:)];

id menuSequenceAction=[CCSequence actions:menuFaceAction, menuCallAction, nil];

[vBackground runAction:backgroundSequenceAction];

[vMenu runAction:menuSequenceAction];

其中调用的removeNode函数如下:

-(void) removeNode:(id)vNode

{

CCNode *node=vNode;

if (node.parent!=nil)

{

[self removeChild:node cleanup:YES];

}

}

改成直接removeChild掉两个CCSprite,就不崩溃了:

[self removeNode:vBackground];

[self removeNode:vMenu];

问题解决:猜想是两个CCSprite同一时间开始的两个CCAction后同时调用removeNode函数,但是一个调到了,一个调用不到。想来这个是一个cocos2d的bug。

MPMoviePlayerViewController完成通知无效

问题描述
今天做Geely,在cocos2d中加video,使用MPMoviePlayerViewController类。

代码如下:
// play video
NSString *videoPath=[[NSBundle mainBundle] pathForResource:@"110414_Gilly_Mix" ofType:@"mov"];
NSURL *videoUrl=[NSURL fileURLWithPath:videoPath];
MPMoviePlayerViewController *player= [[MPMoviePlayerViewController alloc] initWithContentURL:videoUrl];
player.view.backgroundColor = [UIColor blackColor];
player.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
player.moviePlayer.movieControlMode = MPMovieControlModeHidden;
[[[player moviePlayer] backgroundView] setBackgroundColor:[UIColor blackColor]];
[[[CCDirector sharedDirector] openGLView] addSubview:player.view];

[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(movieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];

[[player moviePlayer] play];

问题解决
通知这段去掉object,改为:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(movieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];

调用成功,问题解决,但是不知道原因。