`
luliangok
  • 浏览: 816440 次
文章分类
社区版块
存档分类
最新评论

[Cocoa]深入浅出 Cocoa 之 Plugin

 
阅读更多

深入浅出 Cocoa 之 Plugin

罗朝辉(http://blog.csdn.net/kesalin)

CC 许可,转载请注明出处

在前文深入浅出 Cocoa 之 Framework中讲解了 Framework,接下来讲解 plugin。如果你对 Framework 还不太熟悉的话,请阅读那篇文中,在本例中使用到了 framework,并在本文中没有详细讲述其创建和使用过程。

本文代码下载:点击这里

为什么要引入插件?
我们知道编译程序时,会连接相关 framework,通常我们所连接的框架是 Foundation 和 Application 框架。当程序启动运行时,每个被连接到的 framework 都会被加载到该程序的 objc 运行时环境中。如果我们想向正在运行的程序加载新的 framework,那该怎么办呢?答案之一就是使用 plugin 机制。cocoa 的 plugin 机制通常由 NSBundle 类来实现,而实现动态加载的功能由函数 objc_addClass 来完成。一般我们无需与 objc_addClass 这个函数打交道,我们使用 NSBundle 来完成绝大部分与 plugin 相关的工作。

plugin 机制能够让我们开发出高度模块化,可定制以及可扩展的应用程序,并能够让第三方为该应用程序添加新特性。想必很多人都熟悉 Eclipse,Eclipse 的 plugin 机制就非常方便与强大。

NSBundle 简介
束(bundle)是文件系统中的一个目录结构,它将程序会使用到的资源打包在一起。这些资源可包括编译好的代码,nib文件,配置文件,图像,声音,本地化资源等等。束是 Mac OS X 的一个核心特性,应用程序,Framework,插件都是一个束,只是扩展名各异,如应用程序的扩展名为 .app;Framework 的扩展名是 .framework;插件的扩展名默认为 .bundle。

一个 plugin 就是一个 bundle(束),xcode 默认以 .bundle 为扩展名。通常我们使用我们自己定义的扩展名,以便与系统或其他人编写的 plugin 区分开来。我们通过 NSBundle 来载入 bundle,并把其中经过编译的类注册到 objc 运行时中,然后我们就能在程序中使用这些类了;我们也可以使用 bundle 中的所有资源。

plugin 构架
我们可以通过多种途径来实现一个 plugin:
1,定义一个 objc protocol,让 plugin 遵守该 protocol;
2,定义一个基类,让 plugin 继承该基类;
3,定义一个 C 回调函数接口,让 plugin 实现改回调函数;
4,使用 CFPlugIn 来创建 plugin 接口;

在今天的例子中,使用的是第二种情况,这种情况稍稍复杂一些,我们需创建一个 framework 供宿主程序(使用插件的程序)和 plugin 使用,该 framework 的主要职责是提供基类接口。

plugin 的存放目录
通常 plugin 总是存放在以下三个位置:
1,应用程序名.app/Contents/Plug-ins 这是程序的开发者存放随产品发布的插件的地方。
2,~/Library/Application Support/应用程序名/Plug-ins 用户存放个人插件的地方。
3,/Library/Application Support/应用程序名/Plug-ins 系统中供全部用户使用的插件。

在今天的例子中,使用的是第一种情况,即将插件存放在应用程序包中。

创建宿主程序
我们来创建一个名为 PluginDemo 的 cocoa application,该程序含有一个显示已安装 plugin 的 popup button 以及一个执行选中 plugin 的 button。


创建 framework
1,创建名为 PluginFramework 的 framework,向其中添加 plugin 基类:AbstractPlugin。如果你忘记怎样创建和使用 framework,请参看前文:深入浅出 Cocoa 之 Framework


AbstractPlugin 类仅仅提供两个接口:


name 用来标识 plugin,run 用来供宿主程序运行插件。


2,在 PluginDemo 中连接和使用该 framework 来运行插件。如果你忘记怎样连接和使用 framework,请参看前文:深入浅出Cocoa 之 Framework。我们在按钮响应函数中,运行选中的插件。


创建 plugin
1,创建 plugin;


2,连接 PluginFramework;如果你忘记怎样连接和使用 framework,请参看前文:深入浅出Cocoa 之 Framework


3,创建 UI 界面;


4,创建继承自基类的 plugin 子类:PluginOne;

PluginOne 类继承自AbstractPlugin,它仅仅是显示和隐藏一个 window,其实现如下:

5,plugin 设置
下面我们来对 plugin 进行设置,我们可以设置其Principal class,Wrapper Extension(扩展名)。


使用 plugin

1,宿主程序设置
前面说了,在这个例子中,我们打算将插件随宿主程序一起发布,所以其存放位置就在宿主应用程序包中。因此我们需要在宿主程序种添加一个 Add Copy Files 的 build phase,如下所示:


2,载入plugin
在正式的应用中,我们应该在前面提到的三个目录下去查找所有 plugin,因为这三个目录都是 Cocoa 所推荐的 plugin 目录。在这个例子中,演示的是随宿主应用程序一起发布的程序,所以我只扫描了应用程序包中的目录。


该函数在 init 中被调用:

下面提供一个函数扫描前面提到的三个目录,你可以用这个函数提到上面代码中对 loadPlugins 的调用:


显示 plugin 列表的 popupbutton 的内容被绑定到该 plugins 数组,所以程序启动之后,就能显示 plugin 的列表。运行结果如下:

点击运行之后,就能显示出插件主界面:


Reference:
Code Loading Programming Topicsprovides information about writing plug-ins using the Objective-C language.
Bundle Programming Guideprovides an overview to bundles, including their purpose, types, structure, and the API for accessing bundle resources.


分享到:
评论

相关推荐

    深入浅出Cocoa教程

    - [深入浅出Cocoa]之Plugin - [深入浅出Cocoa]之CoreData - [调试]XCode下的iOS单元测试 - [调试]XCode的一些调试技巧 - [版本管理]Mac下配置Git服务器 - [翻译]苹果Cocoa编码规范 以上参考资料提供了详细的讲解和...

    cocoa 学习

    这是本人在学习和使用 Cocoa 开发过程中写过的一些文章,涵盖 runtime,class, message,KVO,多线程,core data,网络,framework,plugin 等各方面。不仅研 究了应该如何使用这些技术,还深入底层探究这些技术是如何实现...

    unity调用窗口Plugin

    Unity是世界上最流行的游戏开发引擎之一,它支持跨平台开发,包括PC、WebGL和Mac等。在Unity中,有时我们需要与操作系统进行交互,比如打开文件选择对话框或另存为对话框,以便用户可以浏览和选择本地文件。本文将...

    【人脸识别】用非常简短的Python代码实现人脸检测

    如果在运行过程中遇到`qt.qpa.plugin: Could not find the Qt platform plugin "cocoa" in ""`的错误,可以通过查阅Stack Overflow上的解决方案来解决。 在Python中,我们主要使用`cv2`模块来进行人脸检测。下面是...

    WebViewPluginTest:重现 Cocoa WebView 错误的示例项目

    WebView插件测试重现以下 Cocoa WebView 错误的示例项目: 当使用WebView秒的范围内举办NSTabView 建议使用setHostWindow:YES的的API WebView类。 这解决了“即使 Web 视图不在实际窗口中,插件和 JavaScript 也依赖...

    eslint-plugin-cocoascript:用于验证CocoaScript的ESLint插件,CocoaScript是可可库JavaScript绑定

    CocoaScript用于插件,并提供对JavaScript和Cocoa资源的访问。 可与任何支持ESLint集成的IDE配合使用,例如等。 有关更多信息,访问: : 安装 您首先需要安装 : $ npm i eslint --save-dev 接下来,安装eslint...

    cordova-plugin-liveperson-test

    XCode 11或更高版本Swift 5.0或Objective-C 有关最新信息,请参阅添加iOS SDK框架-通过CocoaPods推荐该SDK还与CocoaPods兼容,CocoaPods是Swift和Objective-C Cocoa项目的依赖项管理器。 CocoaPods拥有数千个库,可...

    SwiftPlugin:对于Swift实用程序和工具

    是Cocoa项目的依赖项管理器。 您可以使用以下命令进行安装: $ gem install cocoapods 要使用CocoaPods将SwiftPlugin-God集成到您的Xcode项目中,请在您的Podfile指定它: source '...

    cordova-plugin-imlib-ios:适用于iOS的RongCloud IMLib Cordova插件

    Objective-C是苹果的iOS和macOS平台上的主要编程语言,这个标签表明该插件的实现主要依赖Objective-C编写,这意味着它会使用Cocoa Touch框架,并且与Apple的生态系统紧密集成。开发者需要具备Objective-C的基础知识...

    ReplayKitUnityBridge:从iOS创建到Unity的桥梁-公开了Cocoa ReplayKit API。 它允许您录制屏幕,设置要录制的屏幕的有限时间以及接收录制会话的文件

    概要这是一个iOS的Unity插件,可让您记录屏幕并捕获游戏玩法。 它包含内置的Xcode项目。要开始使用它,只需将PluginSource文件夹作为子文件夹拖到以下目录/文件路径中,作为子文件夹到Unity项目中:Assets> Plugins>...

    自定义滚动条

    在本文中,我们将深入探讨如何在不同的编程环境中自定义滚动条,以增强用户体验和界面美观性。 ### 滚动条的基本组成部分 滚动条通常由以下几个部分组成: 1. **轨道**:滚动条的主体部分,用户可以在其中滑动滑块...

    awesome-xcode:Xcode 的精彩片段、插件和附加功能列表

    :large_orange_diamond: 斯威夫特项目应用Alcatraz:Xcode 的包管理器 Carthage:一个简单的、去中心化的 Cocoa 依赖管理器 :large_orange_diamond: Cocoapods:可可依赖管理器 xcodesnippet:用于安装 Xcode ...

    mac hadoop安装hadoop 2.7.3

    2. **安装Hadoop Eclipse Plugin**:Eclipse插件`hadoop-eclipse-plugin-2.7.3.jar`用于在Eclipse中可视化管理Hadoop集群。将这个jar文件复制到Eclipse的plugins目录下,然后重启Eclipse。 3. **配置Hadoop连接**:...

    cocoapods-generate:一个 CocoaPods 插件,可让您轻松地从 podspec 生成工作区

    cocoapods-generate 一个插件,可让您轻松地从 podspec 生成工作区。 无论您是想从库的存储库中完全删除所有 Xcode 项目,还是希望能够专注于 monorepo 的一小部分,单个pod gen命令都将构建一个适合编写、运行、...

    baseview:音频插件UI的低级窗口系统界面

    baseview将特定于平台的窗口API(winapi,cocoa,xcb)抽象为与平台无关的API,但如果不这样做,您就可以编写插件UI。 有兴趣了解有关该项目的更多信息吗? 加入我们的频道#plugin-gui 。 路线图 以下是拟议的里程...

    qt5.0.0 arm 平台上的移植记录

    在不同的操作系统上,默认值不同,例如在Mac OS上为Cocoa,在Windows上为Windows,而在Linux X11环境下则为xcb。如果设备支持OpenGL,则可以选择EGLFS作为平台抽象层。 - `QMAKE_CFLAGS_RELEASE+=-O2-march=armv5te...

    eclipse web开发环境搭建工具包

    1. **Eclipse安装程序**:这可能是Eclipse的最新版本,如"Eclipse-SDK-x.x.x-win32.zip"或"Eclipse-SDK-x.x.x-macosx.cocoa.x86_64.tar.gz",用于在不同操作系统上安装Eclipse。 2. **Web Tools Platform (WTP)**:...

Global site tag (gtag.js) - Google Analytics