-2

I am trying to convert some Objective C code to Swift and can't manage to do it right with subscripting. This is the method I am trying to migrate to Swift:

- (NSArray *)rangesOfSubstringAlphaNumeric:(NSString *)substring rangesLimit:(NSUInteger)rangesLimit {
    NSAssert(rangesLimit, @"A range limit grather than 0 must be specified");
    if (!substring.length) {
        return nil;
    }
    static NSCharacterSet * restrictedCharacters = nil;
    if (!restrictedCharacters) {
        restrictedCharacters = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
    }
    NSArray * substrings = [substring componentsSeparatedByCharactersInSet:restrictedCharacters];
    NSMutableArray * allRanges = [NSMutableArray array];
    NSString *searchedString = self;
    for (NSString *stringToMatch in substrings) {
        if (![stringToMatch isEqualToString:@""]) {
            NSRange aRange;
            NSUInteger lastLocation = 0;
            NSUInteger foundRanges = 0;
            while (foundRanges++ < rangesLimit &&
                   (aRange = [searchedString localizedStandardRangeOfString:stringToMatch]).location != NSNotFound) {
                searchedString = [searchedString substringFromIndex:aRange.location + aRange.length];
                aRange.location = aRange.location + lastLocation;
                lastLocation = aRange.location + aRange.length;
                [allRanges addObject:[NSValue valueWithRange:aRange]];
            }
        }
    }
    return allRanges.count ? [allRanges copy] : nil;
}

I got stuck on the subscripting part since it seems I cannot assign integer values to Indexes and conversion from Index to Int is out of hand for me I'm kind of stuck, this is what I managed to do:

func rangesOfAlphanumeric(substring: String, limit: UInt) -> [Range<String.Index>] {
        guard limit > 0, !substring.isEmpty else {
            if limit == 0 {
                assert(false, "limit must be greather than 0")
            }
            return []
        }
        var searchedString = self
        let substrings = substring.components(separatedBy: NSCharacterSet.restricted)
        for stringToMatch in substrings {
            if !stringToMatch.isEmpty {

//                var aRange: Range<String.Index>?
//                var lastLocation: UInt = 0
//                var foundRanges: UInt = 0

//                while foundRanges < limit,
//                    let tempRange = searchedString.localizedStandardRange(of: stringToMatch),
//                    !tempRange.isEmpty {
//
//                        searchedString = String(searchedString[tempRange.upperBound...])
//                        if let lastLocation = lastLocation {
//                            aRange = temp
//                        }
//                }

            }
        }
    }

UPDATE: Solution below.

Bogdan
  • 402
  • 2
  • 8
  • 18
  • @matt if i wanted to use NSRange I would have used that, what is unclear regarding my question when you just said that I want to convert Objective C to Swift? and use subscripting instead of NSRange? – Bogdan Mar 22 '20 at 16:35

2 Answers2

0

Managed to resolve the issue using the ranges function posted here:

func rangesOfAlphanumeric(substring: String) -> [Range<String.Index>] {
    var searchedString = self
    let substrings = substring.components(separatedBy: NSCharacterSet.restricted)
    return substrings.compactMap { (stringToMatch) -> [Range<String.Index>]? in
        guard !stringToMatch.isEmpty else {
            return nil
        }
        let ranges = searchedString.ranges(of: stringToMatch, options: [
            .diacriticInsensitive,
            .caseInsensitive
        ])

        if let lastRange = ranges.last {
            searchedString = String(searchedString[index(after: lastRange.upperBound)])
        }
        return ranges
    }.flatMap{$0}
}
Bogdan
  • 402
  • 2
  • 8
  • 18
-3

I created this repo with swift 5 is very easy to use all is already set up. you have just to change the IAP ids

The Github repo

Romy
  • 498
  • 9
  • 14