2014-06-27 23 views
7

我知道在調整方法上有無數的資源。但是,是否可以通過私有API調整方法?問題是沒有頭文件。我想從PrivateFramework中的私有類中調用方法,例如(隨機示例)Message.framework方法調整私有框架的方法iOS API

這是用於個人測試,我明白它會被Apple拒絕而被遺忘。

+0

採取

代碼私人的API,你覺得你需要頭文件,你可以逆向工程。看看像'class-dump'或'class-dump-z'這樣的工具。很多人也在網上發佈了反向工程頭文件。然後,將該標題作爲源文件包含在項目中。如果您遇到反向工程頭文件不編譯的問題,通常您只需手動檢查它們,並刪除不需要的'#imports',或者只是修剪頭文件以僅包含函數,重新感興趣。 – Nate

+0

這就是我最初的做法,並認爲必須有一個更簡單的方法。無論如何,我可以調整這個私人API謝謝布賴恩(見下文)。問題在於其他框架無法調整。即如果我直接從我的測試代碼中調用該方法,我會得到調整後的函數,但如果在某個其他框架中調用了該方法,則它不會調用我的調整函數。 –

+0

您可能需要發佈一個新的後續問題。另外,請具體說明。你知道哪些API會變得很有用,你是說當你的應用程序的進程中調用了API,但是直接由框架調用(而不是你的代碼),那麼調整不起作用? – Nate

回答

9

您可以使用NSClassFromString獲取Class並使用運行時庫執行方法調整。不需要頭文件。你只需要知道類名和方法簽名。

sel_getUid時,可以使用@selector(somePrivateMethod)給你的錯誤有關somePrivateMethod是無效的選擇。如果你曾經試圖做任何事情(因爲頭不可用)從my Xcode plugin

SEL sel = sel_getUid("codeDiagnosticsAtLocation:withCurrentFileContentDictionary:forIndex:"); 
Class IDEIndexClangQueryProviderClass = NSClassFromString(@"IDEIndexClangQueryProvider"); 

Method method = class_getInstanceMethod(IDEIndexClangQueryProviderClass, sel); 
IMP originalImp = method_getImplementation(method); 

IMP imp = imp_implementationWithBlock(^id(id me, id loc, id dict, IDEIndex *idx) { 
    id ret = ((id (*)(id,SEL,id,id,id))originalImp)(me, sel, loc, dict, idx); 

    // do work 

    return ret; 
}); 

method_setImplementation(method, imp); 
+0

它編譯,但不攪拌我想要的方法... –

+0

發生了什麼?還要確保這些代碼確實運行...把它放在'+ [加載]' –

+0

代碼肯定正在運行。但是,爲了驗證這一點,我可以調用私有API並查看它是調用原始方法還是調用原始方法。我嘗試了這一點,我得到:「無法識別的選擇器發送到類」這意味着我的私人api根本沒有被調用。我使用了聲明的類,例如:[IDEIndexClangQueryProviderClass codeDiagnosticsAtLocation:0 withCurrentFileContentDictionary:0 forIndex:NULL] –

0

在該類上創建一個類別併爲要調用的方法添加聲明。然後你可以實例化一個類的實例並調用該方法。

這也適用於單元測試代碼中的私有方法。

+0

我不想添加一個方法,我試圖替換一個方法..你是否暗示聲明該方法將取代現有的方法? –

+0

聲明該方法將提供訪問方法來調整它。在這個問題上,投訴是沒有標題方法。通過創建一個類別,您可以有效地爲您想要調整的方法創建一個標題方法。 – zaph

+0

沒有理由在這裏使用類別,因爲這不是真正的類別,這是一個應該避免的混淆技術。如果問題在於框架是私人的,並且您沒有標題,只需對標題(或您感興趣的單個方法)進行逆向工程,然後將該標題包含在項目中。沒有理由將它作爲*類別*。 OP缺少私有API開發中的一項基本技術,即開發您需要的反向工程頭文件。這是這類問題的標準模式。 – Nate