[原]Delphi调用IOS三方SDK(OC的静态库文件)

  • 主题发起人 主题发起人 DelphiTeacher的专栏
  • 开始时间 开始时间
D

DelphiTeacher的专栏

Unregistered / Unconfirmed
GUEST, unregistred user!
Delphi调用OC的静态库文件


大家好,我是DelphiTeacher,大家有什么第三方SDK调用的需求可以找我,
比如微信支付,支付宝支付,百度地图,消息推送等第三方的SDK,

另外,我也是OrangeUI的作者,
所以在这里给OrangeUI做个广告,也欢迎加入OrangeUI技术支持群: 10900297
很多用Delphi开发APP的公司、朋友都使用了OrangeUI,










Delphi调用OC的静态库文件,十分方便简单,下面我以微信SDK为示例:


(一):前期准备
第三方SDK一般都会在官网有详细的配置教程和对应开发语言的示例DEMO,要十分的仔细阅读,
我会先大致浏览一下流程,下载对应的SDK开发包和示例DEMO,
示例DEMO很重要,毕竟它里面包含调用SDK内类和方法的过程,虽然是ObjectiveC语言,但是对我们用DELPHI调用这个SDK的时间很有参考价值。
像微信开放平台SDK,
官网:
https://open.weixin.qq.com/

创建一个应用:


配置应用(一般是包名和签名):

然后仔细看官方指导:

只需要看IOS的接入指南:

以上的官方接入指南虽然是XCode下面的,但是我们需要仔细的看,DELPHI调用三方库,
不同点就是多了一步把ObjectiveC的头文件翻译成DELPHI的pas文件而已,绝大部分的配置和注意事项都和XCode下面差不多。因为接入指南中包含怎么使用这个库。






(二):下载开发包

开发包里有静态库文件(.a),以及头文件(.h),
当然静态库文件有些是不带后缀的,直接一个文件名,应该很好辨认出来,体积最大的那个文件就是了,
例如微信的SDK,如下:

libWeChat.a是静态库,
WXApi.h和WXApiObject.h是头文件,


我一般把libWeChat..a放在工程目录下,




(三):仔细阅读官方文档
首先,创建一个工程,Platform切换到IOS,打开工程属性,左边VersionInfo标签,
BoundID中填入我们的微信应用的BoundID,如下:

然后新建一个单元做为接口单元,单元名可以是iOS.Weixin.pas,
微信的接口文档里写着这么一段话,

告诉XCode开发者需要在工程中链接上:
SystemConfiguration.framework,libz.dylib,libsqlite3.0.dylib,libc++.dylib。
那么我们DELPHI开发人员需要在Delphi的uses部分引用相关的单元文件,
比如libz.dylib对应的是System.Sqlite单元,
Libz.dylib对应的是System.ZLib单元,
SystemConfiguration.framework的话,就需要在SDKManager中添加SystemConfiguration框架。
自己实现IOS的SystemConfiguration框架
$(SDKROOT)/System/Library/Frameworks
在Delphi中的Options->SDK Manger里,选中iOS Device下的iPhoneOS SDK,加入SystemConfiguration。自己实现iOSapi.SystemConfiguration.pas接口单元。




还有,一般用到的单元有:
iOSapi.Foundation,
MacApi.ObjectiveC,
iOSApi.CocoaTypes,
iOSApi.CoreGraphics,
iOSApi.UIKit,
iOSApi.OpenGLES,
iOSApi.CoreLocation,
Macapi.ObjCRuntime,
Macapi.Helpers,




在uses部分之后,写上链接静态库的编译指令,
{$LINK libWeChatSDK.a}
因为我把libWeChatSDK.a放在工程目录下面了,所以不用注明路径


像文档中提到的都是很重要的:








(四):翻译头文件
然后要翻译ObjectiveC的类声明,
最好有ObjectiveC的基础。
就好比Windows下面我们用Delphi调用C++(或其他语言)的DLL一样,
也要把C++的接口文件转换成Pascal语言的接口文件,


先来转换WXApi.h中的WXApi类,
仔细看如下图,

模式如下(GUID使用快捷键Ctrl+Shift+G生成):
类名=interface(父类)//
[GUID]
//在这里写上对象的方法
end;


类名Class=interface(父类Class)//
[GUID]
//在这里写上类的方法
end;
T类名=class(TOCGenericImport<类名Class, 类名>);

所以这次,要转换的类名为WXApi,它的父类为NSObject,如下:
WXApi=interface(NSObject)//
[GUID]
//在这里写上对象的方法
end;


WXApiClass=interface(NSObjectClass)//
[GUID]
//在这里写上类的方法
end;
TWXApi=class(TOCGenericImport<WXApiClass,WXApi>);








转换方法:
+(BOOL) registerApp:(NSString *)appid;
转换为Delphi之后如下,{}是注释:
function registerApp(appid:NSString{*}):Boolean;cdecl;
注意:后面加上cdecl,
多个参数的转换示例:
+(BOOL) registerApp:(NSString *)appid withDescription:(NSString *)appdesc;
转换为Delphi后如下:
[MethodName('registerApp:withDescription:')]
function registerAppwithDescription(appid:NSString{*};appdesc:NSString{*}):Boolean;cdecl;








并且放在WXApiClass的声明中:

而WXApi没有对象的方法,所以,就空在那里:



转换完之后,写一个导入OC类的函数:

{$O-}
function WXApi_FakeLoader : WXApi; cdecl; external 'libWeChatSDK.a' name 'OBJC_CLASS_$_WXApi';
{$O+}






好了,接下来就能调用了,
以类方法registerApp来示例:
TWXApi.OCClass.registerApp(NSStr(FAppID));






接下来我们转一个有对象属性的类:

OC中类的属性,转换成Delphi的,
需要写一个访问函数和写入过程,
如下这个属性:
@property (nonatomic, retain) NSString* openID;
转换成之后为:
function openID:NSString{*};cdecl;
procedure setOpenID(openID:NSString{*});cdecl;
然后把它们放入类声明中:



Delphi创建OC的对象为:
var
ABaseReq:BaseReq;
begin
ABaseReq:=TBaseReq.Alloc;































作者:DelphiTeacher 发表于2016/7/3 21:46:40 原文链接
阅读:0 评论:0 查看评论

查看更多...
 
后退
顶部