Giter VIP home page Giter VIP logo

bolts-objc's People

Contributors

bklimt avatar bolinfest avatar chuganzy avatar clang13 avatar coeur avatar dhirenp avatar flovilmart avatar grantland avatar hramos avatar ide avatar jrg-developer avatar jvenegas avatar keith avatar lucasderraugh avatar mingflifb avatar mrplants avatar nlutsenko avatar noobs2ninjas avatar peymano avatar richardgroves avatar richardjrossiii avatar rogernolan avatar roremeol avatar ruiaaperes avatar saniul avatar toddkrabach avatar travisjeffery avatar valeriyvan avatar wiruzx avatar wzs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bolts-objc's Issues

No facility for automatically generating array of results for grouped tasks

Hi,

Fantastic framework! From what I can see, there's no facility for automatically creating an array of the results from grouped tasks (using taskForCompletionOfAllTasks:). Errors and exceptions are collected, but not the results. Of course this can be done from the array of tasks manually, but I just wanted to confirm I wasn't missing something, or that (more likely) this was intentionally left unimplemented.

Thanks,

J

Blank view for BFAppLinkReturnToRefererView

According to the guide, you can either setup the view explicitly:

self.returnToRefererView = [[BFAppLinkReturnToRefererView alloc] initWithFrame:CGRectZero];
self.returnToRefererController = [[BFAppLinkReturnToRefererController alloc] init];
self.returnToRefererController.view = self.returnToRefererView;

Or implicitly, by not creating and assigning a BFAppLinkReturnToReferrerView — which will automatically be created when calling -showViewForRefererURL: on the controller.

Looking at the code I see that when this view is automatically created and _attachedToNavController is not nil, it is added to the view hierarchy. OTOH, when manually setting this view, it is not attached to the nav controller. I feel like this violates the Principle of Least Astonishment — ideally the whole return to referrer view would work like a black box that magically works with the least external setup possible.

Quick & dirty fix would be adding a [_attachedToNavController.view addSubview:_view]; on -setView:

Now, on to the real problem, initializing the view with CGRectZero always results in a blank view. Doesn't matter if it's explicitly created and provided to the returnToRefererController or internally created. I've set a few breakpoints throughout the code and the size always ends up being (0, 0, 0, 52) instead of (0, 0, 320, 52).

The only way I can get the view to behave properly (i.e. render as it should, the label and the X button with a blue background) is if I initialize it manually with the target width:

// Using a magic value for the sake of demo
self.returnToRefererView = [[BFAppLinkReturnToRefererView alloc] initWithFrame:CGRectMake(0, 0, 320, 0)];

This is contradictory to the instructions on the README which state that the view should be initialized with CGRectZero.

Couple suggestions

  • Make all control of view attachment and resizing internal to BFAppLinkReturnToRefererController — I like the ability of being able to pass my own implementation of BFAppLinkReturnToRefererView (should I ever need it) but having to write more code (that should be internal to the controller) when I do is cumbersome;
  • Drop both the -init and -initForDisplayAboveNavController: constructors on BFAppLinkReturnToRefererController and add a new one, `-initWithViewController: — I feel like it should make no difference whether it's a navigation controller or a regular view controller, this thing should be a black box

I'd be more than happy to discuss this further and/or advance a solution if you feel like any of this makes sense.

BFAppLinkNavigation methods with custom URL scheme not working

I am using this code to navigate to another native app with the registered URL scheme 'receiver'

NSURL *url = [NSURL URLWithString:@"receiver://"];
[[BFAppLinkNavigation resolveAppLinkInBackground:url] continueWithSuccessBlock:^id(BFTask *task) {
    BFAppLink *link = task.result;
    NSLog(@"resolved link %@", link);
    BFAppLinkNavigation *navigation = [BFAppLinkNavigation navigationWithAppLink:link
                                                                          extras:@{ @"access_token": @"t0kEn" }
                                                                     appLinkData:@{ @"referer_app_link": @{
                                                                                   @"url": @"playlist://",
                                                                                   @"app_name": @"Playlist" }}];
    NSError *error = nil;
    [navigation navigate:&error];
    return nil;
}];

I can make this work with an http:// url like http://spotify.com, but I can't get it to work with a custom URL scheme like receiver://

However, I can open the receiver app using standard method openURL:@"receiver://"
But it's necessary for me to use the BFAppLinkNavigation methods because I need to send the appropriate metadata to let the receiver app generate the proper back button back to the first app. Any ideas why this isn't working?

[Crash] on iPhone 4 iOS 7.0.4 FYI

DEVICE: iPhone 4
IOS VERSION: 7.0.4

Thread : Crashed: com.apple.main-thread
0 ??? 0x2beeb0c4
1 ??? 0x2beebf07
2 ??? 0x2beed69f
3 libdyld.dylib 0x38ba80d0 dyld_stub_binder + 20
4 APP 0x000f3281 38+[BFTask taskForCompletionOfAllTasks:]_block_invoke (BFTask.m:102)
5 APP 0x000f4521 __41-[BFTask continueWithExecutor:withBlock:]_block_invoke_2 (BFTask.m:287)
6 APP 0x000f235d __29+[BFExecutor defaultExecutor]_block_invoke_2 (BFExecutor.m:43)
7 APP 0x000f2795 -BFExecutor execute:
8 APP 0x000f44af __41-[BFTask continueWithExecutor:withBlock:]_block_invoke (BFTask.m:284)
9 APP 0x000f4331 -BFTask continueWithExecutor:withBlock:
10 APP 0x000f4869 -BFTask continueWithBlock:
11 APP 0x000f2f87 +BFTask taskForCompletionOfAllTasks:
12 APP 0x0022544b -PFTaskQueue enqueue:
13 APP 0x001e76a7 -PFObject saveInBackground
14 APP 0x0022303d -PFInstallation saveInBackground
15 APP 0x0004c155 -AppDelegate application:didRegisterForRemoteNotificationsWithDeviceToken:
16 UIKit 0x30d9a473 _UIXXRemoteNotificationRegistrationSucceeded + 150
17 UIKit 0x30d9afe1 _XRemoteNotificationRegistrationSucceeded + 92
18 AppSupport 0x31ae6a97 migHelperRecievePortCallout + 190
19 CoreFoundation 0x2e2db9df __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION
+ 34
20 CoreFoundation 0x2e2db97b __CFRunLoopDoSource1 + 346
21 CoreFoundation 0x2e2da14f __CFRunLoopRun + 1398
22 CoreFoundation 0x2e244c27 CFRunLoopRunSpecific + 522
23 CoreFoundation 0x2e244a0b CFRunLoopRunInMode + 106
24 GraphicsServices 0x32f23283 GSEventRunModal + 138
25 UIKit 0x30ae8049 UIApplicationMain + 1136
26 APP 0x000510fb main (main.m:16)

Errors with Bolts-Pod when using Facbook-iOS-SDK on CI Server

I installed the iOS SDK via CocoaPods. The SDK is working fine.
I then run xctool to test my App via command line and everything is working out good!
But when i try to setup a Mac CI server with xctool and when I clone my project into another dir and try to run the tests via xctool is stops with various errors:

In file included from some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:11:
In file included from some Dir//Pods/Bolts/Bolts/iOS/BFAppLink_Internal.h:11:
some Dir//Pods/Headers/Private/Bolts/BFAppLink.h:1:1: error: expected identifier or '('
../../../Bolts/Bolts/iOS/BFAppLink.h
^
In file included from some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:11:
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink_Internal.h:21:1: error: missing context for method declaration
- (BOOL)isBackToReferrer;
^
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink_Internal.h:23:1: error: expected method body
@end
^
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:23:12: error: cannot find interface declaration for 'BFAppLink'
@interface BFAppLink ()
           ^
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:23:12: error: class extension has no primary class
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:23:12: error: class extension has no primary class
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:23:12: error: class extension has no primary class
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:23:12: error: class extension has no primary class
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:38:30: error: no known class method for selector 'alloc'
    BFAppLink *link = [[self alloc] initWithIsBackToReferrer:isBackToReferrer];
                             ^~~~~
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:39:10: error: property 'sourceURL' not found on object of type 'BFAppLink *'
    link.sourceURL = sourceURL;
         ^
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:40:10: error: property 'targets' not found on object of type 'BFAppLink *'
    link.targets = [targets copy];
         ^
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:41:10: error: property 'webURL' not found on object of type 'BFAppLink *'
    link.webURL = webURL;
         ^
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:55:18: error: 'BFAppLink' cannot use 'super' because it is a root class
    if ((self = [super init])) {
                 ^
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:56:12: error: property 'isBackToReferrer' not found on object of type 'BFAppLink *'
      self.isBackToReferrer = isBackToReferrer;
           ^

I managed to reduce the # of errors by switching to use precompiled headers from off to on in the Pods-Bolt target but these errors above still exists. I am developing an iOS 8 only app.

Any ideas?

Completed set before the task has actually completed

[BFTask waitUntilFinished] shows this quite clearly. Fire off a few tasks, then call waitUntilFinished. The call to wait... will continue (and the task will be set to completed) before the execution block has been called.

This is due to [self runContinuations] always being called after completed/cancelled etc. being set. As a result.

I'm wondering if this is due to thread contention if the was called on the same thread as the executor block, but at the moment the behaviour seems incorrect and results in a lot of additional checks to make sure the task has actually finished.

Prevent duplicate tasks

I have an operation executed when user taps a button, I want to be able to prevent duplicate tasks from being fired.

Bolts framework not parsing parameters that contain a non-breaking space.

When using:
BFURL *parsedUrl = [BFURL URLWithInboundURL:url sourceApplication:sourceApplication];
on url that contain non-breaking space - '%A0' the BFURL doesn't parse all the parameters correctly. So I have to manually change them like so:
NSString *newUrlString = [urlString stringByReplacingOccurrencesOfString:@"%A0" withString:@"%20"];

NSInternalInconsistencyException for seemingly no reason

I am using Bolts via Parse, and am seeing an untrappable bolts error, with Bolts trying to set an error, with no error except the faulted = YES .. with no hint, no clue, no ANYTHING except a stopped app.

The ONLY thing changed between a working app and this was UI settings of another view, a child of the offending view.

Unsettling that Bolts is giving nothing to act on yet is stopping my app from running. For now i am going to toss in a check for a nil error and ignore, but this is frustrating. ;)

The stoppage occurs in:

(void)setError:(NSError *)error { if (![self trySetError:error]) { [NSException raise:NSInternalInconsistencyException format:@"Cannot set the error on a completed task."]; } }

I have no clue how to better describe this, and will try. The last time this happened, i simply stepped back an entire coding day and rebuilt, testing each save and got past the point of the last occurrence, which shows me it is not grounded in that which i am doing but in something very fuzzy.

Same thing happened today, but i will only lose about 2 hours of work to rebuild.

[BFTask waitUntilFinished] wait forever.

I write this testcase for reproduce my issue.When runs to line [BFTask waitUntilFinished], it cannot return.

- (void)testAsyncWait {
  NSLog(@"Start call");
  BFExecutor *backgroundExecutor = [BFExecutor executorWithDispatchQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)];
  BFTask *task = [[[BFTask taskFromExecutor:backgroundExecutor withBlock:^id(BFTask *task) {
    NSLog(@"Background call");
    return nil;
  }] continueWithSuccessBlock:^id(BFTask *task) {
    NSLog(@"Background call2");
    return nil;
  }] continueWithExecutor:[BFExecutor mainThreadExecutor] withSuccessBlock:^id(BFTask *task) {
    NSLog(@"Foreground call");
    return @"Test Result";
  }];
  NSLog(@"Wait call");
  [task waitUntilFinished];
  NSLog(@"End call");
  NSLog(@"%@", task.result);
}

How to execute the tasks parallel in separate thread ?

I have 10 elements in an array. After checking each element in that array, I created the task. Now I want to run all the tasks parallel in different thread not in the main thread. For that I used the BFExecutor.

BFExecutor* executor = [BFExecutor executorWithBlock:^void(void(^block)()) {
                        dispatch_async(dispatch_get_global_queue(0,0), block);
                    }];
BFTask* task = [BFTask taskWithResult: nil];

[[task continueWithExecutor:executor withBlock:^id(BFTask* task) {
   return task2;
}] continueWithBlock:^id(BFTask* task) {
   # Do something with that task.result
   return nil;
}];

Is this is the correct way of using BFTask in separate thread ?
Thanks.

Tasks not chaining properly

I have a BFTask that is returning false to [ob isKindOfClass:[BFTask class]] and yet returns @"BFTask" for NSStringFromClass([obj class]).

Here is a sample project: [email protected]:krusek/Bolts-error.git

-[BFTask waitUntilFinished] does not account for spurious thread wakeup

See https://en.wikipedia.org/wiki/Spurious_wakeup for a description of "spurious wakeup". This seems to apply to NSCondition, as Apple's documentation (Threading Programming Guide) states:

Due to the subtleties involved in implementing operating systems, condition locks are permitted to return with spurious success even if they were not actually signaled by your code. To avoid problems caused by these spurious signals, you should always use a predicate in conjunction with your condition lock.

(The reference documentation for NSCondition also touches on this topic.)

I think something like this may be more correct:

- (void)waitUntilFinished {
    if ([NSThread isMainThread]) {
        [self warnOperationOnMainThread];
    }

    @synchronized (self.lock) {
        if (self.completed) {
            return;
        }
        [self.condition lock];
    }
    while (YES) {
        [self.condition wait];

        @synchronized (self.lock) {
            if (self.completed)
                break;
        }
    }

    [self.condition unlock];
}

Alternately, using dispatch_semaphore_t may provided a simpler implementation.

(Note that I have not actually observed a spurious wakeup. I don't know if this is a possibility on iOS.)

'sharedApplication' is unavailable

I seen the compiling error: 'sharedApplication' is unavailable: not available on iOS (App Extension) in Bolts 1.2.0.

Will you fix that?

BFURL crash on initialization when target_url is null

when target_url is null in the url, a crash occurs in the method initWithURL:forOpenInboundURL:sourceApplication:forRenderBackToReferrerBar:when control reaches this line:

 _targetURL = target ? [NSURL URLWithString:target] : url;

target is of class NSNull

Attempt to read non existent folder

[!] Error installing Bolts
[!] Attempt to read non existent folder /Volumes/ABC/Projects/TestApp/Pods/Bolts.

I encounter this error when pod install

Codesign OSX10.9.5

Hello,
I am deep in trying to properly codesign Bolts for use with the Parse framework and it shows as "..not a valid format..."

I see here that this branch is newer than what Parse is using. I did a build from the master using your scripts and dropped the OSX framework into my project, added copy files phase and checked to code sign like I do for other frameworks. I am getting:

"...bundle format is ambiguous (could be app or framework)"

This is odd as Parse and Sparkle code sign perfectly. Any ideas? I tried re-working the plist but was not successful. I also noticed that your release build script place the OSX Bolts.frameworks inside itself.

-matt

Small hitTargets of BFAppLinkRefererView...

I am having a hard time hitting the link and especially the close button in the BFAppLinkRefererView. Looks like the hit area of both elements is very small; closeButton is 12x12 I believe and label has a height a bit bigger.

image copy

cheers,
H

Carthage compatibility

This issue is for tracking compatibility with Carthage.
OS X version is already compatible, but we need to make Bolts for iOS/tvOS also compile and work great with Carthage.

Cancellation trumps error in -[BFTask taskForCompletionOfAllTasks:]

I have a scenario where I have many, many network requests to make. I would like to provide a BFTask for the completion of all of them.

I want to be able to cancel them if necessary. Also, if any of them individually fail, I would like to abort the ones not yet dispatched. They are all scheduled on a BFExecutor built from an NSOperationQueue.

Each task begins with a check on a shared cancellationToken to see if they should proceed. If the request fails, it returns its error and sets the cancellationToken to true. The remaining tasks in the queue then check the cancellationToken and dutifully return -[BFTask cancelledTask] when they get their turn.

The problem is that the continuation block for -[BFTask taskForCompletionOfAllTasks:] gives cancellations precedent over errors. So, the task for the completion of all of them returns a cancelled task instead of an error. There's an important distinction there. I want to message errors in my user experience, but not cancellations.

I suspect it's intentional, but I don't know why. Is my use of the same cancellation token for canceling and errors discouraged? Or is this something that you could possibly change (to give errors precent over cancellations)?

fetchAsync example no longer valid

In Readme.md, the following function generates the error: Cannot invoke 'fetchInBackgroundWithBlock' with an argument list of type '((PFObject!, NSError!) -> Void)'.

func fetchAsync(object: PFObject) -> BFTask {
    var task = BFTaskCompletionSource()
    object.fetchInBackgroundWithBlock {
        (object: PFObject!, error: NSError!) -> Void in
        if error == nil {
            task.setResult(object)
        } else {
            task.setError(error)
        }
    }
    return task.task
}

Bracket typing autocomplete issue.

When I typing the end bracket ']' for continueWithBlock:, the start bracket '[' cannot be autocomplete with Xcode,but this works good for other case,for example:

[[NSArray array] enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    <#code#>
  }];

NSError cannot be used as a boolean

Refer to fetchAsync via Readme.md when comile with Xcode 6.2 will throw

Optional type 'NSError!' cannot be used as a boolean; test for '!= nil' instead

screen shot 2015-01-01 at 11 21 07 pm

Fix with Xcode suggestion seem to work BTW

2 issues in iOS 9

I've installed Bolts via cocoapods in Xcode 7, now I get 2 errors when I try to build the app.

The first error is "'CFURLCreateStringByAddingPercentEscapes' is deprecated: first deprecated in iOS 9.0 - Use [NSString stringByAddingPercentEncodingWithAllowedCharacters:] instead, which always uses the recommended UTF-8 encoding, and which encodes for a specific URL component or subcomponent (since each URL component or subcomponent has different rules for what characters are valid)."

And the second error is "'sendAsynchronousRequest:queue:completionHandler:' is deprecated: first deprecated in iOS 9.0 - Use [NSURLSession dataTaskWithRequest:completionHandler:] (see NSURLSession.h"

The errors are in two different Files, the first is in BFAppLinkNavigation.m, the second in BFWebViewAppLinkResolver.m.

Here is the repro: https://github.com/telip007/testPods

Provide a result for taskForCompletionOfAllTasks

I want to do multiple asynchronous tasks in parallel, each of which returns a value, and then when all have completed, get an array of those results.

As of now, taskForCompletionOfAllTasks just returns a result of nil.

Task Cancellation

I was wondering, what is the intended approach to task cancellation?

BFTask only exposes methods for task consumption and continuation, while the cancellation is implemented through BFTaskCompletionSource (which actually just calls internal cancellation methods of BFTask).
There is no way to cancel a BFTask without having a reference to its completion source.

Does this mean that a task producer should keep a reference to all its long-running cancellable task completion sources and expose an interface for identifying and cancelling a specific task?

How to stop BFTask Chain ?

Hi Guys

I have a question "how to stop the BFTask chain, break from the chain execution"

See Commnets

 BFTask *task = [_model getX1Task];

    [[task continueWithBlock:^id(BFTask *task) {
        if (task.error || task.exception || task.isCancelled) {
            
            return nil;
        } else {
            NSDictionary *dic = (NSDictionary *)task.result;
            if ([dic isKindOfClass:[NSDictionary class]])
            {
                if ([self checkX1OK])
                {
                
                    return [_model getX2Task];
                    
                }
                else
                {
                    //here I want break 
                    //so i return nil, but I found the continueWithBlock will still return a new task have a nil result, so the chain automaticall go to below 
                    return nil
                }
            }
        }
    }] continueWithBlock:^id(BFTask *task) {
    //but the code come here, even the before task is return nil 
        if (task.error || task.exception || task.isCancelled) {
            
            return nil;
        }
        else {
            if ([self checkX2OK])
            {
               
                return [_model getX3Task];
            }
            else
            {
                //here want break 
                //so i return nil
                return nil
            }
        }
    }] ;

I found why the nil case return default task in BFTask's method
continueWithExecutor:withBlock:

- (BFTask *)continueWithExecutor:(BFExecutor *)executor
                       withBlock:(BFContinuationBlock)block {
    BFTaskCompletionSource *tcs = [BFTaskCompletionSource taskCompletionSource];
    ............................
    //because the result is nil, so it's not a BFTask class
            if ([result isKindOfClass:[BFTask class]]) {
                [(BFTask *)result continueWithBlock:^id(BFTask *task) {
                    ...........
                                        return nil;
                }];
            } else {
                tcs.result = result; //so nil result will go here
            }
        }];
    };
    
    ......
    
    return tcs.task; 
    //so even a nil result will return a default task which is create by BFTaskCompletionSource
}

I have thought a way like this to add one stop:BOOL in the block

typedef id(^BFContinuationWithStopBlock)(BFTask *task, BOOL *stop);
so I can mark &stop = YES, when I want to stop the execution, what are your opinions?

Add 'isFaulted' property to BFTask - keep in line with Android

Hi there, can you please add an "isFaulted" property to BFTask on iOS?
The abstraction for the SDK should be as consistent as possible between Android and iOS - this one of the Bolts framework biggest benefits is that it allows cross-platform teams to write code that is architecturally identical across both the Objective-C and Java SDKs.

The API surface should be identical for all purposes, simply using language-specific mechanisms such as blocks in Obj-C, anonymous interfaces in Java to leverage each language's best native syntax for the API.

Allow setting the result of a task completion source from an existing task.

Frequently, I have to write code like this:

BFTaskCompletionSource *source = [BFTaskCompletionSource taskCompletionSource];
 [.... continueWithBlock:^id(BFTask *task) {
     if (task.faulted) {
         NSError *error = task.error;
         if (error) {
             [source trySetError:error];
        } else {
             [source trySetException:task.exception];
         }
     } else if (task.cancelled) {
         [source trySetCancelled];
     } else {
         [source trySetResult:task.result];
     }

     return task;
 }];

It would be nice if there was an API similar to [source trySetTask:task] instead of having this ugly block of code.

forCompletionOfAllTasksWithResults: exception 'Cannot set the result on a completed task.'

Hello,
I am trying to implement the following logic:

  1. Get user`s posts from Parse
  2. For each post, get a URL of the movie poster from iTunes (func getMovieInfoByITunesID)
  3. After URLs for all posts are received, report completion.

However I get the exception:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Cannot set the result on a completed task.'

The exception rises in this line: tempPost.timeSincePosted = self.getTimeSincePostedfromDate(post.createdAt!)

What does the setResult in the (self.getTimeSincePostedfromDate(post.createdAt!))
has to do with the main task?

func loadFeedPosts() -> BFTask {
    let mainTask = BFTaskCompletionSource()

    let user = PFUser.currentUser()!
    let relation = user.relationForKey("feed")
    let query = relation.query()

    query?.addDescendingOrder("createdAt")

    query?.findObjectsInBackground().continueWithBlock({ (task: BFTask!) -> AnyObject! in
      var tasks = [BFTask]()
      if task.error == nil, let result = task.result {
        let posts = result as! [PFObject]

        for post in posts {
          var tempPost = Post()
          tempPost.userName = (post["createdBy"] as! PFUser).username
          tempPost.timeSincePosted = self.getTimeSincePostedfromDate(post.createdAt!)
          tempPost.profileImageURL = (post["createdBy"] as! PFUser)["smallProfileImage"] as? String

          tasks.append(self.getMovieInfoByITunesID(post["trackID"] as! Int))
         }

      }

      return BFTask(forCompletionOfAllTasksWithResults: tasks)
    }).continueWithBlock({ (task: BFTask!) -> AnyObject! in

      for var i = 0; i < Post.sharedInstance.feedPosts.count; ++i {
         Post.sharedInstance.feedPosts[i].bigPosterImageURL = self.getBigPosterImageURL((task.result as! JSON)[i]["artworkUrl100"].stringValue)
      }

      mainTask.setResult(nil)
      return nil
    })

    return mainTask.task

    }

func getMovieInfoByITunesID(iTunesID: Int) -> BFTask {
      let task = BFTaskCompletionSource()
      ITunesApi.lookup(iTunesID).request({ (responseString: String?, error: NSError?) -> Void in
        if
          //        error == nil,
          let responseString = responseString, let dataFromString = responseString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
            let json = JSON(data: dataFromString)
            task.setResult(json["results"].arrayObject!)
        } else {
          // process error
        }
      })
      return task.task
    }

How to re-throw exceptions?

We are trying to re-throw exceptions as follows. But this way is not only ugly but also takes care of only the last continueWithBlock:.

What would you guys suggest on this?

[[task continueWithBlock:^id(BFTask *task) {
        //throws an exception
        return nil;
    }] continueWithBlock:^id(BFTask *task) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (task.exception) {
                @throw task.exception;
            }
        });
        return nil;
    }];

Avoid using unavailable APIs when linking against app extension targets.

When using Bolts in an app extension development. Some Blots classes have references to [UIApplication sharedApplication] which is not available in an app extension target.

Need a way to avoid the unavailable API usage when linking against app extension targets. Maybe a macro for conditional compile?

linker command failed with exit code 1 when bitcode enabled

using the latest Bolts framework...

Frameworks/Bolts.framework/Bolts(BFExecutor.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Not compatible with UISearchDisplayController

When the returnToRefererView is shown in a setup with a UINavigationController containing a UITableViewController with a searchBar on top, there are a couple of issues:

  • the searchBar can't be scrolled in completely. It's only shown by 10 pt or so, the rest is covered by the navigation bar. It looks like the contentInsets are wrong.
  • when I actually manage to tap that small part of the searchBar to activate UISearchDisplayController, the searchBar is almost completely covered by the returnToRefererView.
  • When search mode is ended, the returnToRefererView is not shown anymore. It is displayed again when search is activated again.
  • when returnToRefererView is closed while search is active, the searchBar moves down not up and reveals an empty gap where the returnToRefererView was before.

To me it looks like it's not a good idea to mess with the navigationBar position!

back view is missing

Hi,

I have a first app which performs a navigation to the second app:

- (IBAction)open:(id)sender
{
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"index" withExtension:@"html"];

    [[BFAppLinkNavigation resolveAppLinkInBackground:url] continueWithSuccessBlock:^id(BFTask *task) {
        BFAppLink *link = task.result;

        BFAppLinkNavigation *navigation = [BFAppLinkNavigation navigationWithAppLink:link
                                                                              extras:@{ @"_test_": @"SURPRISE mother fucker!" }
                                                                         appLinkData:@{ @"referer_app_link": @{
                                                                                                @"url": @"applinks://",
                                                                                                @"app_name": @"AppLinks"
                                                                                                }}];
        NSError *error = nil;

        [navigation navigate:&error];

        return task;
    }];
}

The second app shows up but the back view is missing and the app crashes without any output.. did I miss something ?

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    if (self.appLinkReturnToRefererView) {
        self.appLinkReturnToRefererView.hidden = YES;
    }
    AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

    if (delegate.parsedUrl) {

        self.appLink = [delegate.parsedUrl appLinkReferer];

        [self _showRefererBackView];
    }

    delegate.parsedUrl = nil;

}

- (void) _showRefererBackView {
    if (nil == self.appLinkReturnToRefererView) {
        // Set up the back link navigation view
        BFAppLinkReturnToRefererView *backLinkView  = [[BFAppLinkReturnToRefererView alloc] initWithFrame:CGRectMake(0, 30, 320, 40)];
        self.appLinkReturnToRefererView = backLinkView;
    }
    self.appLinkReturnToRefererView.hidden = NO;
    // Initialize the back link view controller
    BFAppLinkReturnToRefererController *alc =[[BFAppLinkReturnToRefererController alloc] init];
    alc.view = self.appLinkReturnToRefererView;
    // Display the back link view

    [alc showViewForRefererAppLink:self.appLink];
}

EDIT:

If I use the solution without using Bolts, everything is fine. I followed this tutorial:

https://developers.facebook.com/docs/ios/share/#linking

It there an issue in the BFAppLinkReturnToRefererView class ?

navigateToURLInBackground returns NSURLErrorDomain - code 1002

I am using the following code to open the Facebook app:

...
NSString *testUrl = @"fb://";
NSURL *url = [[NSURL alloc] initWithString:testUrl];
[[BFAppLinkNavigation navigateToURLInBackground:url] continueWithBlock:^id(BFTask *task) {
        NSLog(@"yay!");
         return 0;
}];
...

and what I get is an error (generated in BFWebViewAppLinkResolver.m) - NSURLErrorDomain - code 1002.

When I use [[UIApplication sharedApplication] openURL:url] on the same URL it works just fine..

Please help me guys :)
I want to use Bolts to interact with Facebook app.

BFTask cancellation

I looked through issues and documentation and I have no idea how to cancel network task that I do not need anymore.

Using NSProgress as a Cancellation Token

After reading about the interesting idea of cancellation tokens in the readme,
I thought about using NSProgress instead of implementing it on my own.
Are there any known problems or issues with this approach?

Create separate API using Swift generics

Now that Swift has been released, the API design between Android and iOS should be brought together with the support of generics in Swift.

Swift apps should be able to reference a more modern API that takes advantage of generics for task results and continuations.

For legacy purposes it likely makes sense to keep the Objective-C implementation separate, since Obj-C does not support generics. However Swift codebases should not be held back from leveraging the advantages of generics due to the legacy nature of the Bolts Obj-C library.

Custom URL Schemes not supported in [BFAppLinkNavigation navigateToURLInBackground:url]

Similar issue: #38

The method [BFAppLinkNavigation navigateToURLInBackground:url] does not support custom URL Schemes. I personally feel like it should! It supports almost all other forms of opening URL's. The only way to actually navigate to links with custom URL schemes is to implement continueWithBlock:^id(BFTask *task). Is there a specific reason that custom URL schemes are not supported?

For asynch parse operations when testing - waitUntilFinished hangs indefinitely

When you use "waitUntilFinished" at the end of a task, the parse completion block for a somethingInBackground is never called. It works with a dispatch semaphore.

The reason why may be that parse block callbacks always occur on the main thread.

Example:

-(BFTask *)createCorporation {
    NSLog(@"Creating corporation.");
    BFTaskCompletionSource *task = [BFTaskCompletionSource taskCompletionSource];

    PFObject *corporation = [PFObject objectWithClassName:@"AcctCorporation"];
    [corporation setObject:[_locationInfo objectForKey:@"locationName"] forKey:@"name"];
    [corporation setObject:[_locationInfo objectForKey:@"postalCode"] forKey:@"postal"];
    [corporation setObject:[_locationInfo objectForKey:@"country"] forKey:@"country"];
    [corporation setObject:[_locationInfo objectForKey:@"state"] forKey:@"state"];
    [corporation setObject:[_locationInfo objectForKey:@"address"] forKey:@"address"];

    [corporation saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
        NSLog(@"HERE!");  // Never gets called
        if(!error) {
            [task setResult: corporation];
        } else {
            [task setError: error];
        }
    }];
    return task.task;
}

Test:

- (void) testCreateCorporation {
    NSDictionary *userProfile = [NSDictionary dictionaryWithObjectsAndKeys:@"[email protected]", @"email", @"jimbo2s223s4", @"username", @"Jim", @"firstName", @"O'Brien", @"lastName", @"1234", @"pin", @"888xxxx8", @"password", @"619-xxxxxxx", @"cell", nil];
    NSDictionary *locationInfo = @{
                                   @"locationName": @"Joe's Garage",
                                   @"address": @"111 Frank Zappa Street",
                                   @"mainPhone": @"619-xxx-xxxx",
                                   @"postalCode": @"91910",
                                   @"city": @"Palmdale",
                                   @"state": @"California",
                                   @"country": @"USA",
                                   @"position": @"Head Chief and Cook"
                                   };

    __block PFObject *corporation = nil;

    TAPParseSignup *signup = [[TAPParseSignup alloc] initWithLocationInfo:locationInfo andUserProfile:userProfile];
    [[[signup createCorporation] continueWithBlock:^id(BFTask *task) {
        STAssertNil(task.error, @"Error should be nil");
        corporation = [task result];
        return nil;
    }] waitUntilFinished];
    STAssertNotNil(corporation, @"Corp should not be nil.");
    STAssertNotNil([corporation objectId], @"Object id should not be nil");
}

With semaphore working:

- (void) testCreateCorporation {
    NSDictionary *userProfile = [NSDictionary dictionaryWithObjectsAndKeys:@"[email protected]", @"email", @"jimbo2s223s4", @"username", @"Jim", @"firstName", @"O'Brien", @"lastName", @"1234", @"pin", @"8888", @"password", @"619-xxxxxxxx", @"cell", nil];
    NSDictionary *locationInfo = @{
                                   @"locationName": @"Joe's Garage",
                                   @"address": @"111 Frank Zappa Street",
                                   @"mainPhone": @"619-xxx-xxxx",
                                   @"postalCode": @"91910",
                                   @"city": @"Palmdale",
                                   @"state": @"California",
                                   @"country": @"USA",
                                   @"position": @"Head Chief and Cook"
                                   };

    __block PFObject *corporation = nil;
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    TAPParseSignup *signup = [[TAPParseSignup alloc] initWithLocationInfo:locationInfo andUserProfile:userProfile];
    [[signup createCorporation] continueWithBlock:^id(BFTask *task) {
        STAssertNil(task.error, @"Error should be nil");
        dispatch_semaphore_signal(semaphore);
        corporation = [task result];
        return nil;
    }];
    while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW)) {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:20]];
    }
    STAssertNotNil(corporation, @"Corp should not be nil.");
    STAssertNotNil([corporation objectId], @"Object id should not be nil");
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.