我昨天花了好一會,在結束了這方面的工作在各種各樣的解決方案。我不與它完全滿意,但它是我現在做的最好的 - 如果任何人都可以提出任何改進或工作替代我歡迎他們......
總之,對於任何人試圖做一些事情類似。我基於this post中詳細介紹的API解決方案 - 我記錄了我想要模擬的事件序列,然後播放它們。唯一的麻煩是我無法使內置播放API工作(我在底部提到的評論中提到了同樣的崩潰)。經過一段時間在ASM土地上挖掘,我最終寫了自己的版本。
@implementation UIApplication (EventReplay)
///
/// - replayEventsFromFile:
///
- (void)replayEventsFromFile:(NSString *)filename
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:filename];
NSArray* eventList = [[NSArray arrayWithContentsOfFile:filePath] retain];
[self replayEvents:eventList];
}
///
/// - replayEvents:
///
- (void)replayEvents:(NSArray *)events
{
if (!events.count)
return;
NSDictionary *eventDict = [events objectAtIndex:0U];
GSEventRef thisEvent = GSEventCreateWithPlist((CFDictionaryRef)eventDict);
uint64_t eventTime = thisEvent->record.timestamp;
thisEvent->record.timestamp = mach_absolute_time();
mach_port_t appPort = GSCopyPurpleNamedPort([[[NSBundle mainBundle] bundleIdentifier] UTF8String]);
GSSendEvent(&thisEvent->record, appPort);
mach_port_deallocate(mach_task_self(), appPort);
if (events.count <= 1)
return;
NSIndexSet *remainderIndexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, events.count - 1)];
NSArray *remainingEvents = [events objectsAtIndexes:remainderIndexes];
GSEventRef nextEvent = GSEventCreateWithPlist((CFDictionaryRef)[remainingEvents objectAtIndex:0U]);
NSTimeInterval nextEventDelay = GetTimeDelta(nextEvent->record.timestamp, eventTime);
if (nextEventDelay > 0.05)
[self performSelector:@selector(replayEvents:) withObject:remainingEvents afterDelay:nextEventDelay];
else
[self replayEvents:remainingEvents];
CFRelease(nextEvent);
CFRelease(thisEvent);
}
@end
上面的代碼片段顯示了我如何回放事件。我的實現是相當這些混沌 - 你會看到我只好做傻事迴避的事實,如果我一味地用一個定時器來安排接下來的活動有時不火 - 似乎是當延遲太小。您所看到的可怕的黑客似乎使事情的工作確定
不管怎麼說,希望這可以幫助別人以某種方式別人。
來源
2011-02-16 06:40:22
jkp
是否與iOS 5的這種技術的工作?我如何包含GSEventRef? – 2011-12-11 06:16:11