0
votes

Hello every one i am new in swift, i am facing an issue in my program. i have save some data in 'let defaultStudentId = NSUserDefaults.standardUserDefaults()' but every time the application get stopped. defaultStudentId.objectForKey("studentId") this "studentId" is coming from another ViewController.... i need help here is my code and the error.....

import UIKit

class OTPViewController: ViewController {

    @IBOutlet weak var OTP_code: UITextField!
    let defaultStudentId = NSUserDefaults.standardUserDefaults()
    override func viewDidLoad() {
        super.viewDidLoad()

    }


    @IBAction func confirm(sender: AnyObject) {

        let std_id = defaultStudentId.objectForKey("studentId")
        let sendOTPCode = "StudentId=\(std_id)&CODE=\(self.OTP_code.text)&PartnerID=4B67B239CF3735814C063DB89D750481"
        let url = NSURL(string: "http://serviceforonair.examonair.com/AndroidService.asmx/VerifyOTPAndActivateStudent")
        let request = NSMutableURLRequest(URL: url!)
        request.HTTPMethod = "POST"
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.HTTPBody = sendOTPCode.dataUsingEncoding(NSUTF8StringEncoding)
        let task = NSURLSession.sharedSession().dataTaskWithRequest(request){data, response, error in
            if error != nil{
                print(error)
                return
            }
            do{
                let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
                var message : String!
                message = responseString?.stringByReplacingCharactersInRange(NSMakeRange(0, 76), withString: "").stringByReplacingOccurrencesOfString("</string>", withString: "")
                print(self.defaultStudentId)

            }
            catch let jsonException{
                print(jsonException)
            }
        }
        task.resume()



    }
}

Error 2016-08-15 20:14:10.555 DBMCI[21415:143621] * Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFString replaceCharactersInRange:withString:]: Range or index out of bounds' * First throw call stack: ( 0 CoreFoundation 0x000000010dcedd85 exceptionPreprocess + 165 1 libobjc.A.dylib 0x0000000110159deb objc_exception_throw + 48 2 CoreFoundation 0x000000010dcedcbd +[NSException raise:format:] + 205 3 CoreFoundation 0x000000010dcb90ad mutateError + 221 4 Foundation 0x000000010e7c887c -[NSString stringByReplacingCharactersInRange:withString:] + 142 5 DBMCI 0x000000010d62de96 _TFFC5DBMCI17OTPViewController7confirmFPs9AnyObject_T_U_FTGSqCSo6NSData_GSqCSo13NSURLResponse_GSqCSo7NSError__T_ + 902 6 DBMCI 0x000000010d622c87 _TTRXFo_oGSqCSo6NSData_oGSqCSo13NSURLResponse_oGSqCSo7NSError__dT__XFdCb_dGSqS__dGSqS0__dGSqS1___dT + 103 7 CFNetwork 0x0000000111118b49 75-[__NSURLSessionLocal taskForClass:request:uploadFile:bodyData:completion:]_block_invoke + 19 8 CFNetwork 0x000000011112b0f2 __49-[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke + 302 9 Foundation 0x000000010e82f630 __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK + 7 10 Foundation 0x000000010e76a805 -[NSBlockOperation main] + 101 11 Foundation 0x000000010e74d725 -[__NSOperationInternal _start:] + 646 12 Foundation 0x000000010e74d336 __NSOQSchedule_f + 194 13 libdispatch.dylib 0x000000011197a3eb _dispatch_client_callout + 8 14 libdispatch.dylib 0x000000011196082c _dispatch_queue_drain + 2215 15 libdispatch.dylib 0x000000011195fd4d _dispatch_queue_invoke + 601 16 libdispatch.dylib 0x0000000111962996 _dispatch_root_queue_drain + 1420 17 libdispatch.dylib 0x0000000111962405 _dispatch_worker_thread3 + 111 18 libsystem_pthread.dylib 0x0000000111cb74de _pthread_wqthread + 1129 19 libsystem_pthread.dylib 0x0000000111cb5341 start_wqthread + 13 ) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)

2

2 Answers

0
votes

Basically

let std_id = defaultStudentId.objectForKey("studentId")

returns an optional value, so in a String Interpolation "StudentId=\(std_id)"you will get for example "StudentId=Optional(24)" instead of the expected "StudentId=24" which is certainly not what you want.

Assuming the object for key studentId is a String replace the line above with

guard let std_id = defaultStudentId.stringForKey("studentId") else { return }

It checks if the value for key exists and unwraps the optional value on success otherwise it exits the method.

The error message of the crash is related to the line

message = responseString?.stringByReplacingCharactersInRange(NSMakeRange(0, 76), withString: "").stringByReplacingOccurrencesOfString("</string>", withString: "")

Avoid to hard code the range length, calculate it. If you can't, check the length of the string.

0
votes

Your responseString maybe an empty string just (""). So when you try to replace using an range the app crashes. Have a look at responseString's value, check if the character length is greater than 0 and 76.

Add this print(responseString?.characters.count, "responseString's character length") after the var message: String declaration.