Promisekit: Problem with Archive with Xcode Version 7.3.1 (7D1014)

Created on 4 May 2016  路  46Comments  路  Source: mxcl/PromiseKit

I am having issues with creating an archive when using PromiseKit with the newest Xcode. When trying to run an archive task I get a following error:

1. While emitting IR SIL function @_TZFE10PromiseKitCSo20NSNotificationCenter4oncefSSCS_19NotificationPromise for 'once' at /Users/mpigulski/Development/PromiseKitArchiveTest/Pods/PromiseKit/Categories/Foundation/NSNotificationCenter+Promise.swift:22:12 Segmentation fault: 11

I have attached a test project that allows to reproduce this:
PromiseKitArchiveTest.zip

So to reproduce use Xcode Version 7.3.1 (7D1014):

  • open the project using PromiseKitArchiveTest.xcworkspace
  • go for Product -> Archive

Archive will fail. Help.

Most helpful comment

If you're using Cocoapods, and not using anything in the subspec PromiseKit/Foundation, a less hacky solution (not deleting files, changing repo etc.) is to split up the pods in your Podfile:

pod 'PromiseKit/CorePromise'
pod 'PromiseKit/UIKit'
# etc.

All 46 comments

Having the same issue after upgrading to 7.3.1 - my project can build correctly but will not archive.

Many thanks for the test project. Looking into this now and will get back on it ASAP.

Can confirm issue in a CocoaPods project using 3.1.1

I never seem to learn to wait a few days before updating Xcode. Time to roll back...

Unfortunately I haven't had extensive time to research this today, though I am giving it as much time as I can. More than likely though this is simply a swift bug. And although there may be a way we can work around it in our code, it might be simpler to just revert to the prior version of Xcode for the time being or, if you're not using it, remove the NSNotificationCenter+Promise.swift file. In the meantime I will continue looking for a solution.

IME this happens when there are multiple functions with the same name and different signatures.

UPDATE: NSNotificationCenter+Promise/AnyPromise files are removed on this branch.

Easy fix for everybody: https://github.com/rad3ks/PromiseKit/tree/bug/415

Use in Podfile:

pod 'PromiseKit',
    :git => '[email protected]:rad3ks/PromiseKit.git',
    :branch => 'bug/415'

I wonder do we really need

extension NSNotificationCenter {
    public class func _once(name: String) -> NotificationPromise
}

?

@rad3ks This doesn't work for me. I receive the same error whether I'm using your branch or modifying my own local source to match your changes. No sure why it is working for you.

A clash between the class method name and the instance method name would be weird anyway. I would expect much more to be breaking if that were the case. Then again, who knows what's really going on right now.

In my testing, commenting out the class once moved the seg fault down to the instance once. Commenting that one out only moved it down to the init on NotificationPromise. So a name clash does not appear to the be the issue.

I think I rush too much with this one. It worked (somehow) locally. I'm having this issue while running Tests and it just run and passed. I just noticed that CI failed, so sorry for the confusion.

I don't use these categories, so I'm removing those files from bug/415 branch. Feel free to use it as a workaround if you don't use those categories.

Same issue today with Xcode 7.3.1

I just commented out the code (didn't use it) and it works. Seems like this is one of many Xcode bugs.

Seems like a new bug in Swift's type inference? Changing public class NotificationPromise: Promise<[NSObject: AnyObject]> to public class NotificationPromise<T>: Promise<T> prevents the segmentation fault

@mnespor I've tried such a change but other errors occurred.
Can you show full code/commit for fix that seg fault?

@hiromi2424 My code is here: https://gist.github.com/mnespor/be0d60bfefc04e54608b3cf67cbf0c43. To be clear, this is an exploration of the problem, not a fix鈥攊t breaks anything that uses the NSNotificationCenter extension.

There's a tracker for the compiler bug here: https://bugs.swift.org/browse/SR-1427

The problem is also with CLLocationManager+Promise.swift

Looking at https://bugs.swift.org/browse/SR-1427, this was first reported 8 days ago. I suspect that reverting to Xcode 7.3 for now will fix.

This can be fixed temporarily by setting the Swift Compiler Optimization Level for the Pods project to None.

screen shot 2016-05-20 at 10 17 10 am

Another temporary fix if you dont use the particular class NSNotificationCenter+Promise.swift , I commented it in a fork : https://github.com/philippeauriach/PromiseKit/tree/fix-archive-xcode-7
You can use it with cocoapod :
pod 'PromiseKit', :git => 'https://github.com/philippeauriach/PromiseKit.git', :commit => '266cfeb5073277b757efc4a37aa049efc96c596f'

Assuming you don't need that category, here's a post_install step for your Podfile that doesn't require switching to a fork:

post_install do |installer|
    filename = 'Pods/PromiseKit/Categories/Foundation/NSNotificationCenter+Promise.swift'
    contents = '// This file removed due to Swift compiler bug https://bugs.swift.org/browse/SR-1427\n'\
               '// PromiseKit tracking of this issue: https://github.com/mxcl/PromiseKit/issues/415\n'
    system("chmod +w #{filename}; printf \"#{contents}\" > #{filename}; chmod -w #{filename}")
end

Sorry if there's a more standard way than dropping to bash, I'm not an expert in CocoaPods internals or Ruby for that matter.

I wonder do we really need

extension NSNotificationCenter {
    public class func once(name: String) -> NotificationPromise
}

I wish I hadn't added it considering this bug. But sadly we can鈥檛 remove it without breaking API compat. OTOH Swift makes keeping long-term major semantic versions near-impossible (considering bugs and regular syntax changes) so maybe we should just drop it and bump to 4.

NOTE THIS MEANS A PREMATURE BUMP TO PMK4

It doesn't make a lot of sense to have it IMHO. Notifications are inherently multi-fire things but Promises aren't.

Removed my prior comments as they were just noise.

I have personally found once useful and also dislike the idea of a premature version bump. But if it gets the library back into an archivable state with the current Xcode version perhaps it's worth it.

@MikeThomas1 setting optimization level to "none" doesn't seem to fix this issue for me when product archiving. I'm using PromiseKit through CocoaPods 3.0.0

If you're using Cocoapods, and not using anything in the subspec PromiseKit/Foundation, a less hacky solution (not deleting files, changing repo etc.) is to split up the pods in your Podfile:

pod 'PromiseKit/CorePromise'
pod 'PromiseKit/UIKit'
# etc.

I need the subspec PromiseKit/Foundation. @MikeThomas1 's solution is working for me. But I am using Cocoapods and do not want to adjusting the pods project setting manually.
So I just add this script to my podfile and it works fine.

post_install do |installer|
  installer.pods_project.targets.each do |target|
    next unless (target.name == 'PromiseKit')
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_OPTIMIZATION_LEVEL'] = '-Onone'
    end
  end
end

Another work around is to simply remove NSNotificationCenter+Promise.swift from the PromiseKit target. There is no need to edit the file itself or remove the file at all. Just uncheck it's target membership status.

I have the same problem, how can I fix this? I'm trying to submit my library to cocoapod by pod trunk push --allow-warnings ExpSwift.podspec, I already try with changing the compiler level no luck @mxcl Do you have the complete podspec file @lvdaqian her is my podspec

Pod::Spec.new do |s|
    s.name             = "ExpSwift"
    s.version          = "1.0.2"
    s.summary          = "Exp IOS SDK library. Native IOS library for EXP platform."


    s.description      = "Exp IOS SDK library. Native IOS library for EXP platform will allow you to   communicate directly to EXP platform."

    s.homepage         = "https://github.com/ScalaInc/exp-ios-sdk"
    # s.screenshots     = "www.example.com/screenshots_1", "www.example.com/screenshots_2"
    s.license          = 'MIT'
    s.author           = { "Cesar Oyarzun" => "[email protected]" }
    s.source           = { :git => "https://github.com/ScalaInc/exp-ios-sdk.git", :tag => 'v1.0.2' }
    # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'

    s.platform     = :ios, '8.0'
    s.requires_arc = true

    s.source_files = 'Pod/Classes/**/*'


    # s.public_header_files = 'Pod/Classes/**/*.h'
    # s.frameworks = 'UIKit', 'MapKit'
     s.dependency 'PromiseKit','3.0.0'
     s.dependency 'Alamofire','3.1.5'
     s.dependency 'Socket.IO-Client-Swift','4.1.2'
     s.dependency 'JSONWebToken','1.4.1'
   end

My team found a workaround for this issue. We don't explicitly need the swift versions of the NSNotification and CLLocationManager promise categories, so we commented out those files. The Objective-C versions work fine.

This worked for us in our mixed Swift and Objective-C environment. That said, we can't say how this will work for pure Swift environments.

anyone has some kind of solution for using podspec file?

Our sincerest apologies that this fix was over two months delayed. Things should be back to normal now with 3.2.1 which is currently being pushed to the Cocoapods trunk.

Well, during linting another seg fault occurrence was revealed. This appears it will be an issue most of the places that we use pendingPromise(), which is 6 or 7 other classes. The current fix I think could be applied in each case, but I'm going to research a little more to see if I can come up with a better fix and maybe identify the specific compiler issue to include in the open radar along the way. I won't delay much longer though, I promise.

thanks @nathanhosselton I really hope we can fix this I'm just waiting for this to publish my library

Found a better workaround. Patch incoming either later tonight or early tomorrow.

Alright, I _think_ we're good now. 3.2.1 has the fix and is live on the Cocoapods trunk. If you updated to 3.2.1 yesterday you may need to pod cache clean PromiseKit and pod install again.

Again, apologies to all and thanks for bearing with us.

yes I just test it and it works thanks!

Can confirm works on my projects as well. Thanks for the hard work!

In my Podfile I'm specifying pod 'PromiseKit', '3.2.1', but I get an error on pod install indicating that version can't be found.

@joemcsorley specify pod 'PromiseKit', '~> 3.2' and run pod install if you didn't have PromiseKit or pod update if you already had PromiseKit in your project.

@rad3ks even though I specify pod 'PromiseKit', '~> 3.2and then run pod install I keep having PromiseKit 3.2.0being installed and not the desired 3.2.1

`Analyzing` dependencies 
 Downloading dependencies
 **Installing PromiseKit 3.2.0 (was 3.2.0)**
 Generating Pods project
 Integrating client project`

You want: pod update PromiseKit

@mxcl When I do pod update PromiseKit I get this message :

 `[!] /usr/bin/git fetch --unshallow

 error: RPC failed; curl 56 SSLRead() return error -36
 fatal: The remote end hung up unexpectedly
 fatal: early EOF
 fatal: index-pack failed`

@mxcl never mind, it just worked after multiple attempts

This might be a stupid question but I cannot find 3.2.1 in cocoa pods. cocoapods.org Says the latest version is 3.4.0 but when I do a pod search PromiseKit I only see version 3.1.1 as the latest

Not sure what I am missing :/

@johneke as above, you should run pod repo update or similar to update your local cache.

@esteluk I knew it was a stupid question!! Thanks a lot, that worked! 馃憤

Was this page helpful?
0 / 5 - 0 ratings