Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CocoaPods support #1685

Open
bourdakos1 opened this issue May 17, 2023 · 17 comments
Open

Add CocoaPods support #1685

bourdakos1 opened this issue May 17, 2023 · 17 comments
Labels
lang: swift An issue with a Swift client library P3 Priority 3 issue (default for bugs or new feature requests; things we'd like to work on) platform: apple An issue with the macOS or iOS implementation project: connections An issue with the Connections project type: feature-request Desire for new functionality

Comments

@bourdakos1
Copy link
Collaborator

What would you like to be added?

Add CocoaPods support as an alternative to Swift Package Manager for Nearby Connections.

Why is this needed?

Frameworks like Flutter and React Native rely on CocoaPods for their plugin system. This makes it nearly impossible to distribute Nearby Connections as a plugin for these frameworks.

@bourdakos1 bourdakos1 added type: feature-request Desire for new functionality needs-triage Issue still needs to be assigned, labeled and deduplicated P3 Priority 3 issue (default for bugs or new feature requests; things we'd like to work on) platform: apple An issue with the macOS or iOS implementation lang: swift An issue with a Swift client library project: connections An issue with the Connections project and removed needs-triage Issue still needs to be assigned, labeled and deduplicated labels May 17, 2023
@bourdakos1
Copy link
Collaborator Author

CC @IgVelasco @eliabruni

@edgarclerigo
Copy link

What's the status of this? Do we have support for cocoapods already available?

@bourdakos1
Copy link
Collaborator Author

We do not have support for cocoapods and no one on the team is working on this yet. Happy to accept contributions if this is something you're interested in helping out with :)

@IgVelasco
Copy link

@bourdakos1 Hi I might try to get this running on my free time, no promises haha

I noticed the following dependencies:

  dependencies: [
    // Dependencies declare other packages that this package depends on.
    .package(
      name: "abseil",
      url: "https://github.com/bourdakos1/abseil-cpp-SwiftPM.git",
      branch: "cxx17"
    ),
    .package(
      name: "BoringSSL-GRPC",
      url: "https://github.com/firebase/boringssl-SwiftPM.git",
      "0.7.1"..<"0.8.0"
    ),
  ],

Is there a reason to continue using your fork? I think the official has the same code as the fork, it also looks like it might be trickier since I think I should add support to both of these dependencies, and maybe another one that I'm missing

@bourdakos1
Copy link
Collaborator Author

Haha no worries, any attempt is greatly appreciated, even if it doesn’t work out 😊

Nearby needs C++17 support, so my fork has a cxx17 branch that compiles abseil with C++17 instead of 14. Otherwise I get a bunch of linker errors (if I remember correctly). However, if you are able to get this building with the main abseil repo, that would be a huge win!

@IgVelasco
Copy link

@bourdakos1 I've been trying to make a pod of NearbyCoreAdapter, with no luck I want to see if I can build it before in order to debug it a little better, could you give me a hand on building the code, there's a BUILD file but not sure how to use it

Thanks for your support

@bourdakos1
Copy link
Collaborator Author

The BUILD file is for Bazel, which I’m not sure if that even works for NearbyCoreAdapter.

I normally use SPM to build. You should just be able to run “swift build” from the repo root. Hope that helps :) don’t hesitate to reach out if you have any other questions on the build process

@IgVelasco
Copy link

I think I hit a big wall right now.

Im not experience in iOS development in the least. But for what I gathered working around with the library is that it does not support simulator. And what I found is that CocoaPods does not have a way to disable said support, I might be wrong but im getting this kind of errors when building NearbyCoreAdapter usingo cocoapods:

 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator16.4.sdk/usr/include/c++/v1/stdexcept:204:62: error: unknown type name 'string'

@bourdakos1
Copy link
Collaborator Author

Hmm the library should support the simulator. (I’m able to run an app built with the SPM version on the simulator)

“Unknown type name ‘string’” sounds like a C++ header is being exposed to Swift. Do you have a branch I can take a look at?

@IgVelasco
Copy link

Yep that was it, I don't have much of a branch since I'm playing around with it trying to make it work. Now I have a different error but will try to work more on it. Thanks!

This is the podspec that I have for now:

Pod::Spec.new do |s|
  s.name         = 'NearbyCoreAdapter'
  s.version      = '1.0.0'
  s.summary      = 'A summary of your NearbyCoreAdapter package.'
  s.description  = 'A detailed description of your NearbyCoreAdapter package.'
  s.homepage     = 'https://github.com/yourusername/NearbyCoreAdapter'
  s.license      = { :type => 'MIT', :file => 'LICENSE' }
  s.author       = { 'Your Name' => '[email protected]' }
  s.source       = { :git => 'https://github.com/yourusername/NearbyCoreAdapter.git', :tag => s.version.to_s }
  s.swift_version = '5.0'
  s.platform     = :ios, '13.0'
  s.compiler_flags = '-std=c++11'
  s.pod_target_xcconfig = { 'CLANG_CXX_LANGUAGE_STANDARD' => 'c++11' }

  s.public_header_files = "connections/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/*.h"
  s.source_files = [
    "connections/swift/NearbyCoreAdapter/Sources/**/*.h",
    "connections/swift/NearbyCoreAdapter/Sources/**/*.mm",
    'third_party/**/*.mm',
  ]

  # Specify dependencies located in the third_party folder
  s.private_header_files = [
    "third_party/**/*.cpp",
    "third_party/**/*.hpp",
    "third_party/**/*.h"
  ]
  
  s.dependency 'GoogleToolboxForMac'
  s.dependency 'Protobuf', '3.24'

  # You can add other third-party dependencies here
  s.preserve_paths = "NearbyCoreAdapter.framework/*"
  s.xcconfig = {
    'FRAMEWORK_SEARCH_PATH[sdk=iphoneos*]' => '$(inherited) "$(PODS_ROOT)/NearbyCoreAdapter"',
    'OTHERCFLAGS[sdk=iphoneos*]' => '$(inherited) -iframework "$(PODS_ROOT)/NearbyCoreAdapter"',
    'OTHER_LDFLAGS[sdk=iphoneos*]' => '$(inherited) -framework NearbyCoreAdapter'
}
  # ...
end

@Droppix
Copy link

Droppix commented Mar 14, 2024

Does anyone have a solution for Cocoapods?
I'll take it...

@IgVelasco
Copy link

IgVelasco commented Jan 21, 2025

For anyone interested, as a part of a final project in our collage with a few classmates we adapt it to work in flutter, (not using CocoaPods) side loading the dependency. If you guys want to check it out and even make contributions we will love it!

https://github.com/IgVelasco/nearby_cross

I need to revisit since someone told me its not quite working with nearby latest releases but might be helpful for anyone in this thread :)

@edgarclerigo
Copy link

edgarclerigo commented Jan 22, 2025

I do have a solution for this that doesn't require any code adaptation.

TL;DR: The main idea is to create an XCFramework using the package.swift. Then you could create a Podspec for the XCFramework to import this dependency.

This solution is based on the comments here on this thread: https://forums.swift.org/t/how-to-build-swift-package-as-xcframework/41414/27 , and a LOT of Google search to help me go through some linking errors.

  • Create a clone of this repo locally
git clone --recurse-submodules https://github.com/google/nearby.git

We need to use the recurse submodules, to be sure that we clone everything locally.

  • Create a bash script
#!/bin/bash

set -x
set -e

# Pass scheme name as the first argument to the script
NAME=$1

# Build the scheme for all platforms that we plan to support
for PLATFORM in "iOS" "iOS Simulator"; do

    rm -rf .build
    
    # Remove derived data
    # rm -rf ~/Library/Developer/Xcode/DerivedData/*
    
    case $PLATFORM in
    "iOS")
    RELEASE_FOLDER="Release-iphoneos"
    ;;
    "iOS Simulator")
    RELEASE_FOLDER="Release-iphonesimulator"
    ;;
    esac

    ARCHIVE_PATH=$RELEASE_FOLDER

    # Rewrite Package.swift so that it declaras dynamic libraries, since the approach does not work with static libraries
    perl -i -p0e 's/type: .static,//g' Package.swift
    perl -i -p0e 's/type: .dynamic,//g' Package.swift
    perl -i -p0e 's/(library[^,]*,)/$1 type: .dynamic,/g' Package.swift

    xcodebuild archive -workspace . -scheme $NAME \
            -configuration Release \
            -destination "generic/platform=$PLATFORM" \
            -archivePath $ARCHIVE_PATH \
            -derivedDataPath ".build" \
            DEFINES_MODULE=YES \
            SKIP_INSTALL=NO \
            BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
            OTHER_SWIFT_FLAGS="-no-verify-emitted-module-interface" \

    FRAMEWORK_PATH="$ARCHIVE_PATH.xcarchive/Products/usr/local/lib/$NAME.framework"
    MODULES_PATH="$FRAMEWORK_PATH/Modules"
    mkdir -p $MODULES_PATH

    BUILD_PRODUCTS_PATH=".build/Build/Intermediates.noindex/ArchiveIntermediates/$NAME/BuildProductsPath"
    RELEASE_PATH="$BUILD_PRODUCTS_PATH/$RELEASE_FOLDER"
    SWIFT_MODULE_PATH="$RELEASE_PATH/$NAME.swiftmodule"
    RESOURCES_BUNDLE_PATH="$RELEASE_PATH/${NAME}_${NAME}.bundle"

    echo "BUILD_PRODUCTS_PATH=$BUILD_PRODUCTS_PATH"
    echo "RELEASE_PATH=$RELEASE_PATH"
    echo "SWIFT_MODULE_PATH=$SWIFT_MODULE_PATH"
    echo "RESOURCES_BUNDLE_PATH=$RESOURCES_BUNDLE_PATH"

    # Copy Swift modules
    if [ -d $SWIFT_MODULE_PATH ] 
    then
        cp -r $SWIFT_MODULE_PATH $MODULES_PATH
    else
        # In case there are no modules, assume C/ObjC library and create module map
        echo "module $NAME { export * }" > $MODULES_PATH/module.modulemap
        # TODO: Copy headers
    fi

    # Copy resources bundle, if exists 
    if [ -e $RESOURCES_BUNDLE_PATH ] 
    then
        cp -r $RESOURCES_BUNDLE_PATH $FRAMEWORK_PATH
    fi

done

xcodebuild -create-xcframework \
    -framework Release-iphoneos.xcarchive/Products/usr/local/lib/$NAME.framework \
    -framework Release-iphonesimulator.xcarchive/Products/usr/local/lib/$NAME.framework \
    -output $NAME.xcframework

This will create a XCFramework with support for simulator and a 'real device' .... if you just need that support for the 'real device', just change the ‘for’ cycle in the beginning just to compile for the 'real device'.

When I tested this, I was using an old version of this repo, so in my case, I just need to run the script with the parameter NearbyCoreAdapter and NearbyConnections.

e.g:

sh super-awesome-script.sh NearbyCoreAdapter

You should be able to run this script, using the Products -> Library -> Name described on the Package.swift.

  • On your native module (or anywhere it's better)

on your podspec add this:

s.preserve_paths = 'Frameworks/**/*'
s.vendored_frameworks = ['Frameworks/NearbyConnections/NearbyConnections.xcframework', 'Frameworks/NearbyCoreAdapter/NearbyCoreAdapter.xcframework']
s.xcconfig = { 
    "FRAMEWORK_SEARCH_PATHS" => "\"{PODS_XCFRAMEWORKS_BUILD_DIR}/NearbyConnections\" \"{PODS_XCFRAMEWORKS_BUILD_DIR}/NearbyCoreAdapter\""
  }

This solution was included in a project using ReactNative, where I wasn't able to handle having SPM and Cocoapods on a Native module, with this change I was able to use this repo without any problem. In theory you could use this script to convert any SPM Package into a xcframework, which could be handy.

Hope this helps, the same way it did help me!

EDIT: @jgsobczak if this is a valid solution and it's proved it works (at least it works for me), maybe it could be added to the release process, something like when a new version is created, it could create new XCFrameworks as well

@bourdakos1
Copy link
Collaborator Author

@edgarclerigo this is an interesting solution. Does vendored_frameworks allow for links instead of paths? I wouldn't want to include binaries in the git source, but we could have xcframeworks as release artifacts

@edgarclerigo
Copy link

@edgarclerigo this is an interesting solution. Does vendored_frameworks allow for links instead of paths?

As far as I know, it doesn't.

I wouldn't want to include binaries in the git source, but we could have xcframeworks as release artifacts

The binaries from this project (nearby)?

@bourdakos1
Copy link
Collaborator Author

@edgarclerigo yea, even nearby binaries. The issue with committing binaries is that every change to the binary is like including a new copy of the binary, this makes cloning the repo very slow because the default behavior is to clone the full repo history.

@edgarclerigo
Copy link

@edgarclerigo yea, even nearby binaries. The issue with committing binaries is that every change to the binary is like including a new copy of the binary, this makes cloning the repo very slow because the default behavior is to clone the full repo history.

If it's not a deal breaker to have at least the xcframeworks on your git, you can do the same thing I did, I did a clone a new folder just to generate the xcframeworks, and then created a folder Frameworks on my projects, with the xcframeworks and the podspec

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lang: swift An issue with a Swift client library P3 Priority 3 issue (default for bugs or new feature requests; things we'd like to work on) platform: apple An issue with the macOS or iOS implementation project: connections An issue with the Connections project type: feature-request Desire for new functionality
Projects
None yet
Development

No branches or pull requests

4 participants