0

I have been getting an array index out of range error and then came across this question.

Reference link

And this is the block of code.

import UIKit
import Foundation
import CoreBluetooth

EDIT 1: From what Leo suggested, so the error is gone from this block but index out of range still persists

extension Collection where Index == Int {
    func get(index: Int) -> Element? {
        if 0 <= index && index < count {
            return self[index]
        } else {
            return nil
        }
    }
}

class Sample:UIViewController{
    .......

    //This is where I'm sending data

    func send(){
        if let send1 = mybytes.get(index: 2){
            byteat2 = bytefromtextbox
            print(byteat2)
        }
    }
}

But it doesn't seem to work. I get an error at return self[index] in extension Collection{} I have also tried the following,

byteat2.insert(bytefromtextbox!, at:2)

But it returns an index out of range error.

Can someone help/advice a solution?

nar0909
  • 135
  • 2
  • 14
  • Use append instead of insert. Btw why would you need a get method? just use array subscript and check the array count before trying to access the value at the index – Leo Dabus Dec 18 '17 at 23:29
  • If you really want to implement the get method add a constraint to the index `extension Collection where Index == Int {` and use the indices property to check if the index is valid `return indices.contains(index) ? self[index] : nil` – Leo Dabus Dec 18 '17 at 23:31
  • Another option is to change your index parameter from `Int` to `Index` : `extension Collection { func get(index: Index) -> Element? { return indices.contains(index) ? self[index] : nil } }` – Leo Dabus Dec 18 '17 at 23:34
  • @LeoDabus Hi leo, the above mentioned error is gone but I still get index out of range error? :/ – nar0909 Dec 18 '17 at 23:37
  • Like I said use `append` instead of `insert` – Leo Dabus Dec 18 '17 at 23:38
  • @LeoDabus Hi leo, thanks now its working but I keep frequently getting an error for wrapping optional value before I write to the ble peripheral? I am just wondering if you could suggest an advice while passing ble peripheral using perform segue method and nextview?.peripheral = peripheral Or is there a more stable way to do this? :) but thanks heaps for your response – nar0909 Dec 18 '17 at 23:51
  • Add a guard statement in your second view controller to unwrap your optional element – Leo Dabus Dec 18 '17 at 23:52
  • I have already suggested to use a Singleton approach in a previous question you have asked. No need to pass values around and you can use the same shared instance between your view controllers – Leo Dabus Dec 18 '17 at 23:55
  • @LeoDabus Hi leo, yes I'm aware of that response but it seems to be I'm dealing with realtime communication with my ble. So I cant store it because each view when reading a value it will read a changed value and each view will only change a single value and not the whole byte structure so I'm confused. :/ – nar0909 Dec 19 '17 at 00:00
  • Without looking at your code I can't really answer it but anyway just add a `guard element = element else { return }` before using your optional element in your second view controller – Leo Dabus Dec 19 '17 at 00:02
  • @LeoDabus https://github.com/nar0909/nRFSampleSwiftApp_iOS/tree/master/Basic-Chat-master/Basic%20Chat This is my git repo if you would like to have a look and help me hoe to pass the peripheral from view to view? :/ – nar0909 Dec 19 '17 at 00:04
  • What is the version of your Xcode? Looks like you are using Xcode 8.x • Swift 3.x? You should use Data instead of NSData and if you need it to be mutable just declare it as var. Also Swift native string type is String not NSString. – Leo Dabus Dec 19 '17 at 00:46
  • Another thing you should avoid is declaring variables at global scope. Just create a singleton class and add them there. If you would like to read more about adopting cocoa design patterns https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns.html#//apple_ref/doc/uid/TP40014216-CH7-ID177 – Leo Dabus Dec 19 '17 at 00:47
  • @LeoDabus Thanks Leo, appreciate your response. Will try making changes and update you once its done. cheers :) – nar0909 Dec 19 '17 at 00:50

1 Answers1

0

You should use append instead of insert and just use array subscript instead of creating a get method. You just need check the array count before trying to access the value at the index or even better approach would be checking if the collection indices contains the index:

If you really want to implement a get method add a constraint to the index extension Collection where Index == Int or change your index parameter from Int to Index:


extension Collection  {
    func element(at index: Index) -> Element? {
        return indices.contains(index) ? self[index] : nil
    }
}

let array = ["a","b","c","d"]
array.element(at: 2)   // "c"
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571