2013-02-14 72 views
1

我正在使用框架安裝程序腳本。該腳本需要修改用戶AppDelegate文件並在applicationDidFinishLaunching和applicationWillTerminatate方法的開始或結尾註入幾行代碼。以編程方式修改某人AppDelegate - 類別,子類?

我想過一些選項:

  • 解析的源代碼,並插入在正確的位置線。 (可能很難正確工作,適合每個人的代碼,差不多相當於編寫一個編譯器...)
  • 子類AppDelegate文件(這是可能的嗎?)
  • 類別??

哪一個是最好的選擇?還有其他建議嗎?

+0

我不清楚你想做什麼。首先,如果您使用PyObjC添加子類或類別,那就是PyObjC代碼,而不是ObjC代碼,所以它不會影響iOS應用程序,除非您實際分發一個加載本機應用程序並實時修改它的PyObjC包裝應用程序(除非您嘗試通過MobileSubstrate爲越獄手機執行此操作,在這種情況下,您可能可以從外部注入您的更改)。 – abarnert 2013-02-14 20:41:58

+0

對不起,澄清,它是一個iOS obj-c項目。我正在編寫安裝程序在Python中,它將修改源代碼(作爲文本)。 – 2013-02-14 20:43:10

+0

如果您試圖爲子類添加源代碼,那是一個不同的故事。你可以做到這一點,但是你需要改變他們的xcodeproj/makefile /任何來構建你的新源代碼,並且你還需要改變他們的源代碼或者nib來加載你的子類而不是基類,然後你回到「解析源代碼」。 – abarnert 2013-02-14 20:43:11

回答

0

一個解決方案,我目前正在考慮:

  1. 添加子類的AppDelegate NewAppDelegate.m/h的文件。
  2. 這個子類,做我想要的,然後調用超級方法。
  3. 查找/與NewAppDelegate.m.h在main.m文件替換的AppDelegate

這看起來非常簡單和強大。對此有何想法?這將適用於所有/大多數項目嗎?

+0

我也考慮過這個問題,但沒有發佈,因爲它似乎是不好的實現(更不用說可能讓最終用戶不知道它的混淆)。如果你確實走這條路線,只要確保你負責重新路由**每個UIApplicationDelegate方法。 – mbuc91 2013-02-14 21:05:05

+0

好吧,你在混合類名和文件名--'main.m'不會有任何對'NewAppDelegate.m'的引用。但是,這也非常脆弱 - 它適用於那些項目是使用Xcode 4.2+中的新應用程序嚮導構建的項目,並且誰不會重命名任何內容,但如果某個人的委託名爲MyAppDelegate,或者正在使用其中一個那些在'Foo.framework'內創建'FooAppDelegate'的可移植性庫? – abarnert 2013-02-14 21:05:29

+0

@ mbuc91:如果你是子類,你不需要重新路由所有的東西;你只是繼承了你沒有重新定義的基類中的所有方法。 – abarnert 2013-02-14 21:06:15

1

如果您確實需要修改AppDelegate而完全不需要開發人員的任何干預,並且您可以修改xcodeproj和nib而不是源代碼,那麼有一種方法可以實現。

首先,確保你的類被編譯進去,並且你的類的一個實例被創建在nib中。

現在,這裏就是你要做的:

  • 定義-[AHHackClass applicationDidFinishLaunching]方法,做你的額外的東西,然後調用[self originalApplicationDidFinishLaunching]
  • -[AHHackClass awakeFromNib:]中,使用objc運行時調用將-[AHHackClass applicationDidFinishLaunching]方法複製到應用程序委託爲-[originalApplicationDidFinishLaunching],然後使用方法調換來交換兩個方法的實現。
  • 做同樣的swizzle applicationWillTerminate

請參閱JRSwizzle瞭解一些使該方法變得更容易的代碼,以及MethodSwizzling at CocoaDev的某些背景。

但是,可能有一個更簡單的方法來做到這一點:是否真的需要從應用程序代理的applicationDidFinishLaunchingapplicationWillTerminate方法中調用額外的東西?難道你不能只在你的awakeFromNib中收聽通知並在那裏處理事情嗎?

如果出於某種原因,你不能這樣做,你可以在開發者的指示中放一行,從applicationDidFinishLaunching方法中調用你的方法嗎?

+0

我正在尋找可能使用swizzling。我的答案有什麼優勢? – 2013-02-14 21:01:25

+0

如果你只是想開始使用它,你可以使用[Injection for Xcode](http://injectionforxcode.com)。 – mbuc91 2013-02-14 21:06:27

+0

在你的答案中混合使用的好處在於,你不需要對他們的委託被調用的內容,它的源代碼是什麼樣的(或它在哪裏)等做任何假設。在運行時,它們的委託類保證是'[[[UIApplication sharedApplication]委託]類]'。 – abarnert 2013-02-14 21:14:14