【问题标题】:Getting Compile Errors When Using Private API in XCode在 XCode 中使用私有 API 时出现编译错误
【发布时间】:2016-01-29 19:07:52
【问题描述】:

我正在尝试使用 Apple Private API 为 iPhone 编写应用程序。 这仅用于个人开发目的。它不会被提交到应用商店,所以我不必担心被拒绝。

我已按照此视频中的说明进行操作,但我不太确定如何修复这些编译错误:

这是 Youtube 链接:https://www.youtube.com/watch?v=OLX7b_KZIvg

如果您不想观看 Youtube 视频,这些是产生这些错误的步骤:

  1. 从此网址下载私有框架头文件:https://github.com/kennytm/iphone-private-frameworks/tree/master
  2. 解压下载的文件
  3. 将需要的类复制到Xcode PrivateFrameworks路径下,我的路径是: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/PrivateFrameworks (我使用了 TelephonyUtilities.framework)
  4. 在 Xcode 中创建一个新项目(我使用的是 7.2 版)
  5. 转到项目/构建设置并将“框架搜索路径”值设置为 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/PrivateFrameworks (您的路径可能略有不同)
  6. 转到 Project/General 并将库 TelephonyUtilities.framework 添加到“链接的框架和库”部分

注意:1.此时,您应该可以无错误地构建 2. 还应该在左侧面板的项目文件夹中看到私有框架。

  1. 现在,如果您向项目中的 ViewController.h 添加标头并进行构建,则会收到上图所示的错误。

这是我的 ViewController.h 文件:

#import <UIKit/UIKit.h>
#include <TelephonyUtilities/TUCallCenter.h>  // <<<<< This line causes the compilation errors

@interface ViewController : UIViewController


@end

我使用私有 API 的原因是我希望我的应用接受来电,而公共 API 不允许。

任何解决此问题的帮助或指针将不胜感激。

谢谢

【问题讨论】:

  • 您是否可以使用此私有 API 自动接听电话
  • 我有一段时间再试一次,但我不相信我曾经修过它。

标签: ios objective-c iphone xcode iphone-privateapi


【解决方案1】:

如果有人想知道,我需要的解决方法非常简单。 幸运的是,我不需要 TUCallCenter 类中提供的所有功能。 我只需要一些,我可以将不必要的行注释掉。

以下是对 TUCallCenter.h 头文件的更改:

/* Generated by RuntimeBrowser
   Image: /System/Library/PrivateFrameworks/TelephonyUtilities.framework/TelephonyUtilities
 */

#include "TUCallModelState.h"  // <<< Had to add this because TUCallModelState is used below

@interface TUCallCenter : NSObject {
    TUCallModelState *_callModelState;
}

//@property (nonatomic, readonly, retain) TUCall *activeVideoCall;
//@property (nonatomic, readonly) BOOL anyCallIsEndpointOnCurrentDevice;
//@property (nonatomic, readonly) BOOL anyCallIsHostedOnCurrentDevice;
//@property (nonatomic, readonly) unsigned int callCountOnDefaultPairedDevice;
//@property (nonatomic, readonly, copy) NSArray *callGroupsOnDefaultPairedDevice;
@property (nonatomic, retain) TUCallModelState *callModelState;
//@property (nonatomic, readonly, copy) NSArray *callsHostedElsewhere;
//@property (nonatomic, readonly, copy) NSArray *callsHostedOrAnEndpointElsewhere;
//@property (nonatomic, readonly, copy) NSArray *callsOnDefaultPairedDevice;
//@property (nonatomic, readonly, copy) NSArray *callsWithAnEndpointElsewhere;
//@property (nonatomic, readonly, copy) NSArray *conferenceParticipantCalls;
//@property (nonatomic, readonly) unsigned int currentAudioAndVideoCallCount;
//@property (nonatomic, readonly, copy) NSArray *currentAudioAndVideoCalls;
//@property (nonatomic, readonly) unsigned int currentCallCount;
//@property (nonatomic, readonly, retain) NSArray *currentCallGroups;
//@property (nonatomic, readonly, copy) NSArray *currentCalls;
//@property (nonatomic, readonly, retain) TUCall *currentVideoCall;
//@property (nonatomic, readonly) unsigned int currentVideoCallCount;
//@property (nonatomic, readonly, copy) NSArray *currentVideoCalls;
//@property (nonatomic, readonly, copy) NSArray *displayedCalls;
//@property (nonatomic, readonly, retain) TUCall *incomingCall;
//@property (nonatomic, readonly, copy) NSArray *incomingCalls;
//@property (nonatomic, readonly, retain) TUCall *incomingVideoCall;
//
//+ (id)_sharedInstanceWithDaemonDelegate:(id)arg1;
//+ (BOOL)emergencyCallBackModeIsActive;
+ (BOOL)isInCallServiceProcess;
//+ (void*)sharedAddressBook;
+ (id)sharedInstance;
//
//- (void).cxx_destruct;
//- (id)_allCalls;
//- (id)_callGroupsFromCalls:(id)arg1;
//- (void)_callStatusChangedInternal:(id)arg1;
//- (id)_dial:(id)arg1 callID:(int)arg2 service:(int)arg3 sourceIdentifier:(id)arg4 dialType:(int)arg5 uniqueProxyIdentifier:(id)arg6;
//- (id)_dialWithRequest:(id)arg1 completion:(id /* block */)arg2;
//- (void)_handleCallControlFailure:(id)arg1;
//- (id)activeVideoCall;
//- (BOOL)allCallsAreOfService:(int)arg1;
//- (BOOL)allCallsPassTest:(id /* block */)arg1;
//- (int)ambiguityState;
- (void)answerCall:(id)arg1;
//- (void)answerCall:(id)arg1 withSourceIdentifier:(id)arg2;
//- (void)answerCall:(id)arg1 withSourceIdentifier:(id)arg2 wantsHoldMusic:(BOOL)arg3;
//- (void)answerCallWithHoldMusic:(id)arg1;
//- (BOOL)anyCallIsEndpointOnCurrentDevice;
//- (BOOL)anyCallIsHostedOnCurrentDevice;
//- (BOOL)anyCallPassesTest:(id /* block */)arg1;
//- (id)audioAndVideoCallsWithStatus:(int)arg1;
//- (id)audioOrVideoCallWithStatus:(int)arg1;
//- (unsigned int)callCountOnDefaultPairedDevice;
//- (id)callGroupsOnDefaultPairedDevice;
//- (id)callModelState;
//- (id)callPassingTest:(id /* block */)arg1;
//- (id)callPassingTest:(id /* block */)arg1 sortedUsingComparator:(id /* block */)arg2;
//- (id)callPassingTest:(id /* block */)arg1 withOptions:(unsigned int)arg2;
//- (id)callWithCallUUID:(id)arg1;
//- (id)callWithStatus:(int)arg1;
//- (id)callWithUniqueProxyIdentifier:(id)arg1;
//- (id)callsHostedElsewhere;
//- (id)callsHostedOrAnEndpointElsewhere;
//- (id)callsOnDefaultPairedDevice;
//- (id)callsPassingTest:(id /* block */)arg1;
//- (id)callsPassingTest:(id /* block */)arg1 returningNilForEmpty:(BOOL)arg2;
//- (id)callsWithAnEndpointElsewhere;
//- (id)callsWithStatus:(int)arg1;
//- (BOOL)canInitiateCallForService:(int)arg1;
//- (BOOL)canInitiateCalls;
//- (BOOL)canInitiateVoicemailCall;
//- (BOOL)canMergeCalls;
//- (BOOL)canUseThumperOverRelayForIncomingAndOutgoingCalls;
//- (id)conferenceCall;
//- (id)conferenceParticipantCalls;
//- (unsigned int)countOfCallsPassingTest:(id /* block */)arg1;
//- (unsigned int)currentAudioAndVideoCallCount;
//- (id)currentAudioAndVideoCalls;
//- (unsigned int)currentCallCount;
//- (id)currentCallGroups;
//- (id)currentCalls;
//- (id)currentVideoCall;
//- (unsigned int)currentVideoCallCount;
//- (id)currentVideoCalls;
//- (void)dealloc;
//- (id)dial:(id)arg1 callID:(int)arg2 service:(int)arg3;
//- (id)dial:(id)arg1 callID:(int)arg2 service:(int)arg3 sourceIdentifier:(id)arg4 uniqueProxyIdentifier:(id)arg5;
//- (id)dial:(id)arg1 service:(int)arg2;
//- (id)dialEmergency:(id)arg1;
//- (id)dialEmergency:(id)arg1 sourceIdentifier:(id)arg2;
//- (id)dialVoicemail;
//- (id)dialVoicemailWithSourceIdentifier:(id)arg1;
//- (id)dialWithRequest:(id)arg1;
//- (void)dialWithRequest:(id)arg1 completion:(id /* block */)arg2;
//- (void)disconnectAllCalls;
//- (void)disconnectCall:(id)arg1;
//- (void)disconnectCall:(id)arg1 withReason:(int)arg2;
//- (void)disconnectCurrentCallAndActivateHeld;
//- (void)disconnectNonRelayingCalls;
//- (void)disconnectRelayingCalls;
//- (id)displayedCall;
//- (id)displayedCallFromCalls:(id)arg1;
//- (id)displayedCalls;
//- (void)endActiveAndAnswerCall:(id)arg1;
//- (void)endActiveOrHeldAndAnswerCall:(id)arg1;
//- (void)endEmergencyCallBackMode;
//- (void)endHeldAndAnswerCall:(id)arg1;
//- (void)enteredBackgroundForAllCalls;
//- (void)enteredForegroundForCall:(id)arg1;
//- (void)enumerateCallsInvokingBlock:(id /* block */)arg1 forCallsPassingTest:(id /* block */)arg2;
//- (void)enumerateCallsWithOptions:(unsigned int)arg1 invokingBlock:(id /* block */)arg2 forCallsPassingTest:(id /* block */)arg3;
//- (id)frontmostAudioOrVideoCall;
//- (id)frontmostCall;
- (void)handleCallModelStateChanged:(id)arg1;
//- (void)holdActiveAndAnswerCall:(id)arg1;
//- (id)incomingCall;
//- (id)incomingCalls;
//- (id)incomingVideoCall;
//- (id)initWithDaemonDelegate:(id)arg1;
//- (BOOL)isAddCallAllowed;
//- (BOOL)isAmbiguous;
//- (BOOL)isEndAndAnswerAllowed;
//- (BOOL)isHardPauseAvailable;
//- (BOOL)isHoldAllowed;
//- (BOOL)isHoldAndAnswerAllowed;
//- (BOOL)isMergeable;
//- (BOOL)isSendToVoicemailAllowed;
//- (BOOL)isSwappable;
//- (BOOL)isTakingCallsPrivateAllowed;
//- (void)pullHostedCallsFromPairedHostDevice;
//- (void)pullRelayingCallsFromClient;
//- (void)pullThumperCallFromClientUsingInfo:(id)arg1 completion:(id /* block */)arg2;
//- (void)pushHostedCallsToPairedClientDevice;
//- (void)pushRelayingCallsToHost;
//- (void)pushRelayingCallsToHostWithSourceIdentifier:(id)arg1;
//- (void)resumeCall:(id)arg1;
//- (void)sendFieldModeDigits:(id)arg1;
//- (void)setCallModelState:(id)arg1;
//- (void)swapCalls;
//- (id)videoCallWithStatus:(int)arg1;

@end

如你所见,只剩下几个函数,我就可以构建和运行了。

【讨论】:

  • 您使用了所有框架概念还是只是拖放文件?
  • @SwiftArchitect - 恐怕我不知道框架概念是什么。不过,我确实在 Finder 中复制并粘贴了文件。
【解决方案2】:
NSString *frameworkPath = @"/System/Library/PrivateFrameworks/TelephonyUtilities.framework"];
NSBundle *bundlePath = [NSBundle bundleWithPath: frameworkPath];
if ([bundlePath load]) {
    Class TUCallCenter = NSClassFromString(@"TUCallCenter");
    tucallCenter = [TUCallCenter sharedInstance];
}

这是您使用私有框架动态加载 TUCallCenter 实例的方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-05
    • 2017-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多