2019-09-02 09:58:29 u012265444 阅读数 146
  • osg与opengl混合渲染

    1.认识并简单的应用qt,达到可以做一些自己的小例子 2.qt与osg是如何传递消息的,如何进行通信 3.了解三维是如何显示在里 有问题咨询老师微信,微信号:mikeshizhanbiao

    15307 人正在学习 去看看 师占标

前言

hihi,勇敢的小伙伴儿们大家好,我们有一个项目许久未更新了,所以代码有很长一段时间没有运行过,这两天想参考原项目的功能和设计,所以要运行起来安装到设计人员手机中,给她作为设计的参考,但是运行起来出错不断,原先可以顺利运行的项目报错了。

面对这些突如其来的问题,不怂,错误不可避免,解决就可以了。

正文

因为项目是混编的原因,Swift的使用直接导致了这次错误的出现。

问题出现及解决步骤如下:

首先,Xcode提示:

意思就是Xcode10.1不支持的Swift3.x

那哪里用的Swift3.x呢?不妨编译一下看看。出现错误如图:

 

很清晰了,分别在以上几个马赛克target中使用了Swift3.0,那么如何解决这个问题呢?

在Target中找到Build Settings在搜索框搜索swift language~

把Swift Language Version修改成支持的Swift版本就可以了~

再运行就不会出现上述错误,但是可能会出现别的问题,如果提示OC调用Swift文件中的方法找不到的时候,下面的做法可能会帮助到你:

在类前加@objcMembers就能顺利生成OC方法直接调用就可以啦~

运行项目->成功运行(耶)

如有问题,还请大家指出,多谢各位~

2016-10-21 09:09:00 weixin_34258078 阅读数 5
  • osg与opengl混合渲染

    1.认识并简单的应用qt,达到可以做一些自己的小例子 2.qt与osg是如何传递消息的,如何进行通信 3.了解三维是如何显示在里 有问题咨询老师微信,微信号:mikeshizhanbiao

    15307 人正在学习 去看看 师占标

Swift和Objective-C混编的注意啦

2016-10-19 13:29 编辑: 不灭的小灯灯 分类:iOS开发 来源:仁伯安的简书
 

前言

Swift已推出数年,与Objective-C相比Swift的语言机制及使用简易程度上更接地气,大大降低了iOS入门门槛。当然这对新入行的童鞋们来讲,的确算是福音,但对于整个iOS编程从业者来讲,真真是,曾几何时“高大上”,转瞬之间“矮矬穷”。再加上培训班横行,批量批发之下,iOS再也看不到当年的辉煌。

949086-4009987e29482a25.png

往事不再提,事还是要做滴。iOS10推出后,紧跟着Xcode8也推送了更新,细心者会发现,Xcode8下iOS版本最低适配已变为iOS8.0,加上Swift版本趋于稳定,从某种意义上讲,Swift的时代正式开启,替代Objective-C怕也只是时间问题。当然,在这之前,我们也应做好准备。今年越来的越多的公司,也开始了Swift和Objective-C混编。

我们今天就来看看两者混编中的一些注意事项及问题:

混编

混编也无非两种情况,

  • 在Objective - C工程或者文件使用Swift的文件;

  • 在Swift工程或者文件使用Objective - C文件

在混编的过程中最重要的两个文件:
1. 桥接文件:
桥接文件“ProjectName-Bridging-Header.h”,在首次创建其他文件的时候,会自动生成。如果不小心删除后,也可以手动添加,不过名字必须是“ProjectName-Bridging-Header.h”头文件(名称组成:工程名-Bridging-Header.h),如果名字记不清也可以自己新建Header file后,在Targets-->Build Settings-->Swift Compiler - General-->Objective-C Bridging Header配置文件路径,这个文件主要是Swift使用OC类时使用。

2. Objective-C Generated Interface Header Name文件
这个文件是混编时,系统生成的Swift文件对应的Objective-C的头文件,具体可以在Targets-->Build Settings-->Swift Compiler - General-->Objective-C Generated Interface Header Name进行配置,默认文件名是工程名-Swift.h,一般不做改动。

在Objective - C工程或者文件使用Swift的文件

当在OC文件中调用Swift文件中的类的时候,首先在OC文件中要加上 #import "
ProjectName-swift.h”(名字组成:工程名-swift)

这个文件虽然在工程中看不到,但是她真实存在,编译后,你可以按住Command+单击该文件名,就会看到具体生成的代码。
引入后,具体类的使用,直接按照OC的方式使用即可。

在Swift工程或者文件使用Objective - C文件

当在Swift中使用OC文件的时候,只需在桥接文件即projectName-Bridging-Header.h文件中引入需要的头文件。
具体使用,按照对应的Swift语法结构来即可。

混编注意事项

对于需要混编的Swift类添加@objc声明或继承NSObject或NSObject的子类
class TestClass
{
// 属性
// 实现
}

如果要在Objective-C类中使用TestClass类,应当使用@objc加以声明,或者将TestClass继承自NSObject或NSObject的子类,否则,引入ProductName-Swift.h之后,程序找不到对应类。

使用第三方Framework
  • 设置: target-->build setting -->Packaging -->Defines Module为 “Yes”;

  • 然后,配置文件Target -> Build Phases  -> Link Binary,添加要导入的Framework;

  • 最后,还是要配置桥接文件,比如要使用 abc-lib.framework库中的 abc.h 就要这样配置:#import"abc-lib/abc.h";

Subclass子类问题

对于自定义的类而言,Objective-C的类,不能继承自Swift的类,即要混编的OC类不能是Swift类的子类。反过来,需要混编的Swift类可以继承自OC的类。 注解

OC宏文件

如Swift文件要使用OC中定义的宏,只能使用常量简单宏文件。

Swift独有特性

Swift中有许多OC没有的特性,比如,Swift有元组、为一等公民的函数、还有特有的枚举类型。所以,要使用的混编文件要注意Swift独有属性问题。

案例之Swift中使用OC的block

Swift中使用Closure不能使用Block作为属性进行传值,必须是初始化方法或函数。
Objective-C文件中

#import typedef void (^Myblock)(NSString *arg); 

@interface FirViewController : UIViewController 
//@property (copy, nonatomic) Myblock myBlock; 
//这种作为公共参数的形式,如果在Swift类中去回调的话,是有问题的。提示没有初始化方法,所以使用下面的以Block为参数的方法 

- (void)transValue:(Myblock) block;

@end

下面是.m文件

#import "FirViewController.h" 
@implementation FirViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.view.backgroundColor = [UIColor whiteColor]; 
} 

- (void)transValue:(Myblock)block
{ 
    if (block) 
    { 
        block(@"firBack"); 
    } 
} 
@end

在Swift文件回调:

在Swift使用OC的类时,首先在桥接文件中声明oc的头文件
工程名-Bridging-Header.h这是创建Swift工程的情况下

import UIKit 
class ViewController: UIViewController 
{ 
   override func viewDidLoad() 
    { 
        super.viewDidLoad() 
        self.view.backgroundColor = UIColor.whiteColor() 
    } 
    @IBOutlet weak var goFirst: UIButton! 
    @IBAction func goFirstAction(sender: AnyObject) 
    { 
        let firVC:FirViewController = FirViewController() 
        firVC. transValue { ( arg:String !) -> Void in 
            self.aBtn?.setTitle(arg, forState: UIControlState.Normal)
        } 
        self.navigationController?.pushViewController(firVC, animated: true) 
    }

 

转载于:https://www.cnblogs.com/ruixin-jia/p/5983366.html

2016-06-14 16:42:28 ismilesky 阅读数 2932
  • osg与opengl混合渲染

    1.认识并简单的应用qt,达到可以做一些自己的小例子 2.qt与osg是如何传递消息的,如何进行通信 3.了解三维是如何显示在里 有问题咨询老师微信,微信号:mikeshizhanbiao

    15307 人正在学习 去看看 师占标

概述

Swift的设计的初衷就是摆脱ObjC沉重的历史包袱,毕竟ObjC的历史太过悠久,相比于很多现代化语言它缺少一些很酷的语法特性,而且ObjC的语法和其他语言相比差别很大。随着Swift的改进及Swift开源项目剧增,越来越多的Objective-C工程开始使用Swift混编,不管是在基于Swift工程中或者Objective-C工程中,Swift和Objective-C文件都可以无缝结合。本文首先介绍下Swift与Objective-C混编的基本使用。

Objc与Swift的渊源

通过对swift的了解,大家不难发现Swift和ObjC必然存在着一定的映射关系,例如对于文件的操作使用了字符串的writeToFile方法,在网络请求时使用的NSURLSession,虽然调用方式不同但是其参数完全和做ObjC开发时调用方式一致。原因就是Swift编译器自动做了映射,如下图:(PS:借来的图)

这里写图片描述

Objc和Swift的相互调用

切入正题,当我们使用OC和Swift在工程中进行混编的时候,通俗来说其实Objc文件和swift文件之间的相互调用。不管你的项目是基于Swift还是基于Objc的,无论是Swift中调用ObjC,还是ObjC中调用Swift都是通过头文件暴漏对应接口的,下图说明了这种交互方式:

这里写图片描述


  • Swift调用Objc

下面我们先建个Objc的工程,在Objc工程中新建Swift文件时,(或者在Swift工程新建Objc文件),Xcode会自动提示你是否创建bridging header桥接头文件,点击创建后Xcode会自动为你创建一个桥接头文件。Xcode会自动创建一个名为OC_Swift-Bridging-Header.h桥接头文件如图下图:

这里写图片描述

当然你也可以在Building Settings中自己设置桥接头文件,如下图:

这里写图片描述

创建好OC_Swift-Bridging-Header.h文件后,在OC_Swift-Bridging-Header.h文件中即可import需要提供给Swift的Objective-C头文件,Swift即可调用对应的Objective-C文件。同时Xcode可以自动生成Objective-C对应的Swift接口。

( PS:Objective-C类、协议、属性、方法、扩展、闭包等所有功能都可以无缝地被转换为Swift接口被Swift文件所调用。)


  • Objc调用Swift

Xcode会自动为Project生成头文件以便在Objective-C中调用。在Objective-C类中调用Swift,只需要#import “productModuleName-Swift.h”即可调用,Xcode提供的头文件以Swift代码的模块名加上-Swift.h为命名。
(PS:我这有个通俗的理解方式,不喜勿喷,可能不专业,但是好理解。。 “productModuleName-Swift.h文件可以理解为:这个是Objective-C调用Swift的,你写的swift文件在这个文件里对外提供了OC使用的接口,OC调swift,引入这个文件,相当于直接可以使用对外接口了,你可以通俗理解 平常OC的.h文件留的接口)
在这个头文件中,将包含Swift提供给Objective-C的所有接口、Appdelegate及自动生成的一些宏定义。

在大部分情况下,Objective-C都可以无缝地调用Swift,但是由于Swift相对于Objective-C多了一些新特性,比如泛型、元组、枚举的等,所以Swift暴漏给Objective-C的接口多了一些限制,因此Swift只能暴露在Objective-C中有效的接口。

2019-04-19 10:59:11 u011212112 阅读数 364
  • osg与opengl混合渲染

    1.认识并简单的应用qt,达到可以做一些自己的小例子 2.qt与osg是如何传递消息的,如何进行通信 3.了解三维是如何显示在里 有问题咨询老师微信,微信号:mikeshizhanbiao

    15307 人正在学习 去看看 师占标

刚刚在Android项目 混编了flutter特意记录一下
具体的操作可以参考该链接flutter 与Android原生的混编
这次简要介绍下具体的流程,以及实际使用用遇到的问题

混编前的准备

  1. 新建flutter model
    注意不是flutter project,因为是要将flutter当做lib去引入Android项目里面,新建的flutter model 在项目的层级上要放到 与Android项目相同的层级 例如下图:
    项目层级结构然后把flutter项目中lib下面的内容迁移到新建的flutter model中 记得添加相应的 引用在pubspec.yaml 文件中
  2. 在Android项目的 setting_gradle 里面添加 如下代码:
setBinding(new Binding([gradle: this]))
evaluate(new File(
        settingsDir.parentFile,
        'flutter_staff/.android/include_flutter.groovy'
))

其中需要注意的是:这段代码是针对你的项目名称是app的设置,如果你的项目名称不是app则需要下面的设置,需要制定你的 app项目名称,不然的话编译一直会出错

setBinding(new Binding([gradle: this, mainModuleName: 'airport']))
evaluate(new File(
        settingsDir.parentFile,
        'flutter_staff/.android/include_flutter.groovy'
))
  1. 然后sync下项目,此时项目中会出现很多东西,
    sync后的结构其中flutter的lib就是咱们需要引入的,因为我用了阿里的 boost 所以会多生成一个boost的lib,其他的都是flutter运行需要的,没细究
  2. 在 app modul 中 build.gradle 中添加设置,添加依赖,至此前期准备就完成了
 implementation project(path: ':flutter')

正式调用

  1. 先说下通常的调用方式:
  • 调用flutter生成 view 并添加到当前activity
View flutterView = Flutter.createView(
        MainActivity.this,
        getLifecycle(),
        "route1"
);
FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(600, 800);
layout.leftMargin = 100;
layout.topMargin = 400;
addContentView(flutterView, layout);

  1. 通过添加fragment的方式去添加,需要在activity的xml文件里面添加一个FrameLayout
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fl_flutter_view, Flutter.createFragment("route1"));
fragmentTransaction.commit();
  1. 我用了 boost,他的调用方式与其他的不同,他封装了整个调用方式,与activity进行绑定,通过寻址的方式去调用,以及释放资源,还提供了页面传值,
  • 具体使用包括先创建 MyApplication 继承自flutterApplication ,然后在onCreate方法里面添加-
  FlutterBoostPlugin.init(object : IPlatform {
            override fun getApplication(): Application {
                return this@MyApplication
            }

            /**
             * get the main activity, this activity should always at the bottom of task stack.
             */
            override fun getMainActivity(): Activity {
                return BaseKTActivity.sRef?.get()!!
            }

            override fun isDebug(): Boolean {
                return false
            }

            /**
             * start a new activity from flutter page, you may need a activity router.
             */
            override fun startActivity(context: Context, url: String, requestCode: Int): Boolean {
                return PageRouter.openPageByUrl(context, url, requestCode)
            }

            override fun getSettings(): Map<*, *>? {
                return null
            }
        })

其中 pageRoute是一个页面路由

public class PageRouter {

    public static final String FLUTTER_PAGE_URL = "sample://flutterPage";

    public static boolean openPageByUrl(Context context, String url) {
        return openPageByUrl(context, url, 0);
    }

    public static boolean openPageByUrl(Context context, String url, int requestCode) {
        try {
            if (url.startsWith(FLUTTER_PAGE_URL)) {
                context.startActivity(new Intent(context, FlutterPageActivity.class));
                return true;
            }  else {
                return false;
            }
        } catch (Throwable t) {
            return false;
        }
    }
}

具体的FlutterpageActivity

class FlutterPageActivity : BoostFlutterActivity() {
    /**
     * 页面传参
     */
    override fun getContainerParams(): MutableMap<Any?, Any?> {
        var params = mutableMapOf<Any?, Any?>()
        params.put("opEmployeeID", LoginInfoUtils.getEmployeeID())
        params.put("deptID",LoginInfoUtils.getDeptID())
        params.put("token", LoginInfoUtils.getToken())
        params.put("registrationId", "")
        params.put("dataCommission", LoginInfoUtils.getDataCommission())
        return params
    }

    override fun onRegisterPlugins(registry: PluginRegistry?) {
        GeneratedPluginRegistrant.registerWith(registry)
    }

    /**
     * 路由-该名字配置在flutter中,会根据返回的名字打开相应的flutter页面
     */
    override fun getContainerName(): String {
        return "VipBindingState"
    }
}

至此,也就全部搞定了
总结下需要注意的问题:

  1. Android项目与flutter model要在同一层级
  2. 如果是多渠道打包,需要在flutter module的build.gradle中配置渠道信息
  3. 如果Android项目app module的名字不是”app“,需要配置project.rootProject.ext.mainModuleName。 问题解决
  4. 后续打包遇到的问题debug包正常,release包跳转flutter页面崩溃
    解决方法:配置flutter混淆https://www.jianshu.com/p/338422e3ecc1
    目前也就这些了
2018-12-26 12:08:45 wz597002248 阅读数 221
  • osg与opengl混合渲染

    1.认识并简单的应用qt,达到可以做一些自己的小例子 2.qt与osg是如何传递消息的,如何进行通信 3.了解三维是如何显示在里 有问题咨询老师微信,微信号:mikeshizhanbiao

    15307 人正在学习 去看看 师占标


近期进行项目重构工作,将原先的项目拆分成子framework解耦,因为原项目是OC和swift混编的,遇到了很多framework层的混编问题,总结一下


在最上层项目中混编

swift引用swift

直接互相引用即可

swift引用OC

通过bridge桥接文件

OC引用swift

通过#import “项目名-Swift.h”

OC引用OC

直接#import “类名.h”


在Framework层内混编

swift引用swift

直接使用

swift引用OC

在项目的公共.h中加入需要引用的OC头文件,然后在项目的Build Phases中将其头文件移动到Public中

OC引用swift

#import <项目名/项目名-Swift.h> 如

#import <home_device_add_sdk/home_device_add_sdk-Swift.h>

OC引用OC

直接#import “类名.h”


跨Framework层混编

swift引用swift

添加项目依赖关系
需要import整个新的项目

swift引用OC

添加项目依赖关系
需要import整个新的项目

OC引用swift

添加项目依赖关系
#import <项目名/项目名-Swift.h> 如

#import <home_device_add_sdk/home_device_add_sdk-Swift.h>

OC引用OC

添加项目依赖关系
#import <项目名/类名.h>


上层项目引用Framework时混编

swift引用swift

添加项目依赖关系,然后在引用处添加import语句
import framework名,如

import home_device_add_sdk

swift引用OC

添加项目依赖关系即可

OC引用swift

添加项目依赖关系
#import <项目名/项目名-Swift.h> 如

#import <home_device_add_sdk/home_device_add_sdk-Swift.h>

OC引用OC

添加项目依赖关系
#import <项目名/被引用类名> 如

#import <home_device_add_sdk/HWDevAddResultController.h>

代码混编

博文 来自: xiaouncle

OC与Swift混编

阅读数 9521

OC与swift混编

阅读数 1554

没有更多推荐了,返回首页