Realm-cocoa: Build as static library with the new CocoaPods version

Created on 12 Mar 2018  路  14Comments  路  Source: realm/realm-cocoa

Goals

Use static libraries to reduce the launch time on a app (https://github.com/artsy/eigen/pull/2561)

Expected Results

RealmSwift would build

Actual Results

Redacted/Pods/RealmSwift/RealmSwift/LinkingObjects.swift:56:57: error: cannot convert value of type 'UInt' to expected argument type 'Int'
                                                 count: UInt(len)))
                                                        ^~~~~~~~~

Redacted/Pods/RealmSwift/RealmSwift/LinkingObjects.swift:120:48: error: cannot convert value of type 'Int' to expected argument type 'UInt'
        return notFoundToNil(index: rlmResults.index(of: object.unsafeCastToRLMObject()))
                                    ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                    UInt(                                               )
Redacted/Pods/RealmSwift/RealmSwift/LinkingObjects.swift:129:48: error: cannot convert value of type 'Int' to expected argument type 'UInt'
        return notFoundToNil(index: rlmResults.indexOfObject(with: predicate))
                                    ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                    UInt(                                    )
Redacted/Pods/RealmSwift/RealmSwift/LinkingObjects.swift:138:48: error: cannot convert value of type 'Int' to expected argument type 'UInt'
        return notFoundToNil(index: rlmResults.indexOfObject(with: NSPredicate(format: predicateFormat,
                                    ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                    UInt(
Redacted/Pods/RealmSwift/RealmSwift/LinkingObjects.swift:152:45: error: cannot convert value of type 'UInt' to expected argument type 'Int'
            return unsafeBitCast(rlmResults[UInt(index)], to: Element.self)
                                            ^~~~~~~~~~~

Redacted/Pods/RealmSwift/RealmSwift/List.swift:31:40: error: cannot convert value of type 'Int' to expected argument type 'UInt'
        return descriptionWithMaxDepth(RLMDescriptionMaxDepth)
                                       ^~~~~~~~~~~~~~~~~~~~~~
                                       UInt(                 )
Redacted/Pods/RealmSwift/RealmSwift/List.swift:35:62: error: cannot convert value of type 'UInt' to expected argument type 'Int'
        return RLMDescriptionWithMaxDepth("List", _rlmArray, depth)
                                                             ^~~~~
                                                             Int( )
Redacted/Pods/RealmSwift/RealmSwift/List.swift:85:47: error: cannot convert value of type 'Int' to expected argument type 'UInt'
        return notFoundToNil(index: _rlmArray.index(of: dynamicBridgeCast(fromSwift: object) as AnyObject))
                                    ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                    UInt(                                                                 )
Redacted/Pods/RealmSwift/RealmSwift/List.swift:94:47: error: cannot convert value of type 'Int' to expected argument type 'UInt'
        return notFoundToNil(index: _rlmArray.indexOfObject(with: predicate))
                                    ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                    UInt(                                   )
Redacted/Pods/RealmSwift/RealmSwift/List.swift:118:75: error: cannot convert value of type 'UInt' to expected argument type 'Int'
            return dynamicBridgeCast(fromObjectiveC: _rlmArray.object(at: UInt(position)))
                                                                          ^~~~~~~~~~~~~~

Redacted/Pods/RealmSwift/RealmSwift/List.swift:122:41: error: cannot convert value of type 'UInt' to expected argument type 'Int'
            _rlmArray.replaceObject(at: UInt(position), with: dynamicBridgeCast(fromSwift: newValue) as AnyObject)
                                        ^~~~~~~~~~~~~~

Redacted/Pods/RealmSwift/RealmSwift/List.swift:304:81: error: cannot convert value of type 'UInt' to expected argument type 'Int'
        _rlmArray.insert(dynamicBridgeCast(fromSwift: object) as AnyObject, at: UInt(index))
                                                                                ^~~~~~~~~~~

Redacted/Pods/RealmSwift/RealmSwift/List.swift:318:36: error: cannot convert value of type 'UInt' to expected argument type 'Int'
        _rlmArray.removeObject(at: UInt(index))
                                   ^~~~~~~~~~~

Redacted/Pods/RealmSwift/RealmSwift/List.swift:342:37: error: cannot convert value of type 'UInt' to expected argument type 'Int'
        _rlmArray.replaceObject(at: UInt(index), with: dynamicBridgeCast(fromSwift: object) as AnyObject)
                                    ^~~~~~~~~~~

Redacted/Pods/RealmSwift/RealmSwift/List.swift:358:34: error: cannot convert value of type 'UInt' to expected argument type 'Int'
        _rlmArray.moveObject(at: UInt(from), to: UInt(to))
                                 ^~~~~~~~~~

Redacted/Pods/RealmSwift/RealmSwift/List.swift:374:38: error: cannot convert value of type 'UInt' to expected argument type 'Int'
        _rlmArray.exchangeObject(at: UInt(index1), withObjectAt: UInt(index2))
                                     ^~~~~~~~~~~~

Redacted/Pods/RealmSwift/RealmSwift/ObjectiveCSupport.swift:151:24: error: invalid redeclaration of 'convert(object:)'
    public static func convert(object: @escaping (Int, Int) -> Bool) -> RLMShouldCompactOnLaunchBlock {
                       ^
Redacted/Pods/RealmSwift/RealmSwift/ObjectiveCSupport.swift:144:24: note: 'convert(object:)' previously declared here
    public static func convert(object: @escaping RLMShouldCompactOnLaunchBlock) -> (Int, Int) -> Bool {
                       ^
Redacted/Pods/RealmSwift/RealmSwift/ObjectiveCSupport.swift:146:27: error: cannot convert value of type 'UInt' to expected argument type 'Int'
            return object(UInt(totalBytes), UInt(usedBytes))
                          ^~~~~~~~~~~~~~~~

Redacted/Pods/RealmSwift/RealmSwift/Results.swift:96:87: error: cannot convert value of type 'UInt' to expected argument type 'Int'
        return Int(rlmResults.countByEnumerating(with: state, objects: buffer, count: UInt(len)))
                                                                                      ^~~~~~~~~

Redacted/Pods/RealmSwift/RealmSwift/Results.swift:130:48: error: cannot convert value of type 'Int' to expected argument type 'UInt'
        return notFoundToNil(index: rlmResults.index(of: object as AnyObject))
                                    ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                    UInt(                                    )
Redacted/Pods/RealmSwift/RealmSwift/Results.swift:139:48: error: cannot convert value of type 'Int' to expected argument type 'UInt'
        return notFoundToNil(index: rlmResults.indexOfObject(with: predicate))
                                    ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                    UInt(                                    )
Redacted/Pods/RealmSwift/RealmSwift/Results.swift:148:48: error: cannot convert value of type 'Int' to expected argument type 'UInt'
        return notFoundToNil(index: rlmResults.indexOfObject(with: NSPredicate(format: predicateFormat,
                                    ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                    UInt(
Redacted/Pods/RealmSwift/RealmSwift/Results.swift:161:72: error: cannot convert value of type 'UInt' to expected argument type 'Int'
        return dynamicBridgeCast(fromObjectiveC: rlmResults.object(at: UInt(position)))
                                                                       ^~~~~~~~~~~~~~

Redacted/Pods/RealmSwift/RealmSwift/Sync.swift:595:77: error: cannot convert value of type 'Int' to expected argument type 'UInt'
                                                block(Progress(transferred: transferred, transferrable: transferrable))
                                                                            ^~~~~~~~~~~
                                                                            UInt(      )

Steps to Reproduce

  1. Create a Gemfile:
source 'https://rubygems.org'

gem 'cocoapods', git: 'https://github.com/CocoaPods/CocoaPods.git'
gem 'cocoapods-core', git: 'https://github.com/CocoaPods/Core.git'
  1. Run bundle install
  2. Change your Podfile to use
use_frameworks!(false)
use_modular_headers!
  1. Run bundle install && bundle exec pod install
  2. Try to build the app

Version of Realm and Tooling

Realm framework version: ? 3.1.1

Realm Object Server version: ? -

Xcode version: ? 9.2

iOS/OSX version: ? 11.2

Dependency manager + version: ? CocoaPods (master)

O-Community T-Help

All 14 comments

I have the same issue

/Pods/RealmSwift/RealmSwift/LinkingObjects.swift:56:57: Cannot convert value of type 'UInt' to expected argument type 'Int'
/Pods/RealmSwift/RealmSwift/LinkingObjects.swift:126:48: Cannot convert value of type 'Int' to expected argument type 'UInt'
/Pods/RealmSwift/RealmSwift/LinkingObjects.swift:135:48: Cannot convert value of type 'Int' to expected argument type 'UInt'
/Pods/RealmSwift/RealmSwift/LinkingObjects.swift:144:48: Cannot convert value of type 'Int' to expected argument type 'UInt'
/Pods/RealmSwift/RealmSwift/LinkingObjects.swift:158:45: Cannot convert value of type 'UInt' to expected argument type 'Int'
/Pods/RealmSwift/RealmSwift/List.swift:31:40: Cannot convert value of type 'Int' to expected argument type 'UInt'
/Pods/RealmSwift/RealmSwift/List.swift:35:62: Cannot convert value of type 'UInt' to expected argument type 'Int'
/Pods/RealmSwift/RealmSwift/List.swift:85:47: Cannot convert value of type 'Int' to expected argument type 'UInt'
/Pods/RealmSwift/RealmSwift/List.swift:94:47: Cannot convert value of type 'Int' to expected argument type 'UInt'
/Pods/RealmSwift/RealmSwift/List.swift:118:75: Cannot convert value of type 'UInt' to expected argument type 'Int'
/Pods/RealmSwift/RealmSwift/List.swift:122:41: Cannot convert value of type 'UInt' to expected argument type 'Int'
/Pods/RealmSwift/RealmSwift/List.swift:304:81: Cannot convert value of type 'UInt' to expected argument type 'Int'
/Pods/RealmSwift/RealmSwift/List.swift:318:36: Cannot convert value of type 'UInt' to expected argument type 'Int'
/Pods/RealmSwift/RealmSwift/List.swift:342:37: Cannot convert value of type 'UInt' to expected argument type 'Int'
/Pods/RealmSwift/RealmSwift/List.swift:358:34: Cannot convert value of type 'UInt' to expected argument type 'Int'
/Pods/RealmSwift/RealmSwift/List.swift:374:38: Cannot convert value of type 'UInt' to expected argument type 'Int'
/Pods/RealmSwift/RealmSwift/ObjectiveCSupport.swift:151:24: Invalid redeclaration of 'convert(object:)'
/Pods/RealmSwift/RealmSwift/ObjectiveCSupport.swift:146:27: Cannot convert value of type 'UInt' to expected argument type 'Int'
/Pods/RealmSwift/RealmSwift/Results.swift:96:87: Cannot convert value of type 'UInt' to expected argument type 'Int'
/Pods/RealmSwift/RealmSwift/Results.swift:130:48: Cannot convert value of type 'Int' to expected argument type 'UInt'
/Pods/RealmSwift/RealmSwift/Results.swift:139:48: Cannot convert value of type 'Int' to expected argument type 'UInt'
/Pods/RealmSwift/RealmSwift/Results.swift:148:48: Cannot convert value of type 'Int' to expected argument type 'UInt'
/Pods/RealmSwift/RealmSwift/Results.swift:161:72: Cannot convert value of type 'UInt' to expected argument type 'Int'
/Pods/RealmSwift/RealmSwift/Sync.swift:615:77: Cannot convert value of type 'Int' to expected argument type 'UInt'

This is an odd one. The documentation claims that NSUInteger is bridged to Swift as Int, and that does in fact seem to be the case when I create a brand new Xcode project. However, using the actual Realm xcode project or the cocoapods-generated project for a dynamic framework, it's actually bridged to UInt, and I don't see anything obvious that could be causing this to be different.

NSUInteger is supposed to be bridged as Int for system frameworks like Foundation/AppKit/UIKit, and as UInt for user frameworks.
Maybe using static libraries changes this behavior ?

https://lists.swift.org/pipermail/swift-users/Week-of-Mon-20160111/000848.html
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170130/031327.html
https://pspdfkit.com/blog/2018/first-class-swift-api-for-objective-c-frameworks/#code-nsuinteger-code-vs-code-int-code-and-code-typedef-code

NSUInteger is supposed to be bridged as Int for system frameworks like Foundation/AppKit/UIKit, and as UInt for user frameworks.

That explains. The content of ${PODS_ROOT}/Headers/Private/Realm/Realm.modulemap is

module Realm [system] {
    umbrella header "Realm.h"

    export *
    module * { export * }

    explicit module Private {
        header "RLMAccessor.h"
        header "RLMArray_Private.h"
        header "RLMCollection_Private.h"
        header "RLMListBase.h"
        header "RLMObject_Private.h"
        header "RLMObjectBase_Dynamic.h"
        header "RLMObjectBase_Private.h"
        header "RLMObjectSchema_Private.h"
        header "RLMObjectStore.h"
        header "RLMOptionalBase.h"
        header "RLMProperty_Private.h"
        header "RLMRealm_Private.h"
        header "RLMRealmConfiguration_Private.h"
        header "RLMResults_Private.h"
        header "RLMSchema_Private.h"
        header "RLMSyncConfiguration_Private.h"
        header "RLMSyncUtil_Private.h"
    }

    explicit module Dynamic {
        header "RLMRealm_Dynamic.h"
        header "RLMObjectBase_Dynamic.h"
    }
}

If I manually remove the [system] mark in the modulemap file, those errors will disappear.

The [system] tag is seemingly being added by cocoapods, so I guess the question is if it's doing that for a good reason. If it is we can probably deal with NSUInteger being bridged differently, but I don't want to spend time putting in hacks to make it work if we don't need to.

@ainopara Thanks! I've reported your findings in the CocoaPods issue https://github.com/CocoaPods/CocoaPods/issues/7589

CocoaPods has now merged a fixed for this, so it should work if you use CocoaPods master.

RealmSwift compiles with the fix from CocoaPods, but two warnings have appeared in our app:

Umbrella header for module 'Realm' does not include header 'RLMMigration_Private.h'
Umbrella header for module 'Realm' does not include header 'RLMSyncManager_Private.h'

I'm using Cocoapods 1.5.0 and RealmSwift with use_modular_headers!, and still run into this issue. How can I fix this issue

@rdd7 Cocoapods 1.5.0 still have issues and it will be fixed in 1.5.1, which I'm waiting for too. https://github.com/CocoaPods/CocoaPods/issues/7589#issuecomment-381437801

Still having the issue with Cocoapods 1.5.2, any updates ?

Tried on CocoaPods 1.5.3 with RealmSwift 3.3.2 and with use_modular_headers! and it is working.

Warnings mentioned by @MaximeLM are still appearing on CocoaPods 1.5.3.

If the warnings are still present, please create a new issue if this is to be resolved in Realm.
Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

matteodanelli picture matteodanelli  路  3Comments

TheHmmka picture TheHmmka  路  3Comments

xspyhack picture xspyhack  路  3Comments

carvalho-oak picture carvalho-oak  路  3Comments

dennisgec picture dennisgec  路  3Comments