Sculptor icon indicating copy to clipboard operation
Sculptor copied to clipboard

SCLURLModelMatcher is not able to handle multiple path

Open iducool opened this issue 11 years ago • 1 comments

My understanding is that we can add multiple path in one SCLURLModelMatcher correct me If I am wrong.

URL: http://www.xyz.com/testapp/api/countryList

//Code snippet that is working fine giving me correct class
SCLURLModelMatcher *matcher = [SCLURLModelMatcher matcher];
[matcher addPath:@"/*/*/countryList" forClass:User.class];
//Code snippet that is not working always giving me nil class
SCLURLModelMatcher *matcher = [SCLURLModelMatcher matcher];
[matcher addPath:@"/*/*/*/*/global" forClass:Post.class];
[matcher addPath:@"/*/*/countryList" forClass:User.class];

Is this a bug? If not then please suggest me how can I get out of it.

I have tried to debug and found that problem is in “match:” method. When node will have a multiple children(NSArray *list = node.children); For loop just break by considering first object which may be correct match or not.

iducool avatar Oct 22 '14 12:10 iducool

As I told you earlier, problem only occurs when you will have multiple children at same level. At that time In array of childeren if "*" will come first then our code will not go for exact matching which is actually exist in array but at later index.

One quick and dirty solution is that we should always keep exact match type object first in array of children.

See here my implementation of solution,

- (void)addPath:(NSString *)path forClass:(Class)class
{
    NSParameterAssert(path != nil);
    NSParameterAssert(class != nil);
    //NSParameterAssert([class isSubclassOfClass:MTLModel.class]);

    NSArray *tokens = nil;
    if ([path length] > 0) {
        NSString *newPath = path;
        if ([path hasPrefix:@"/"]) {
            newPath = [path substringFromIndex:1];
        }

        tokens = [newPath componentsSeparatedByString:@"/"];
    }

    SCLURLModelMatcher *node = self;
    for (NSString *token in tokens) {
        NSMutableArray *children = node.children;

        SCLURLModelMatcher *existingChild = nil;
        for (SCLURLModelMatcher *child in children) {
            if ([token isEqualToString:child.text]) {
                node = child;
                existingChild = node;
                break;
            }
        }

        if (!existingChild) {
            existingChild = [[SCLURLModelMatcher alloc] init];
            if ([token isEqualToString:@"#"]) {
                existingChild.matcherType = SCLURLModelMatcherTypeNumber;
            } else if ([token isEqualToString:@"*"]) {
                existingChild.matcherType = SCLURLModelMatcherTypeText;
            } else {
                existingChild.matcherType = SCLURLModelMatcherTypeExact;
            }
            existingChild.text = token;

            __block NSUInteger foundedIndex = node.children.count;

            [node.children enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

                SCLURLModelMatcher *tempMatcher = (SCLURLModelMatcher*) obj;

                if (tempMatcher.matcherType >= existingChild.matcherType) {
                    foundedIndex = idx;
                    *stop = YES;
                }

            }];

            [node.children insertObject:existingChild atIndex:foundedIndex];
            node = existingChild;

        }
    }
    node.matchClass = class;
}

iducool avatar Nov 11 '14 13:11 iducool